// OneScript: ./OInt/tools/Modules/OPI_TypeConversion.os

// MIT License

// Copyright (c) 2023 Anton Tsitavets

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

// https://github.com/Bayselonarrend/OpenIntegrations

// BSLLS:LatinAndCyrillicSymbolInWord-off
// BSLLS:IncorrectLineBreak-off
// BSLLS:UnusedLocalVariable-off
// BSLLS:UsingServiceTag-off

//@skip-check module-structure-top-region
//@skip-check module-structure-method-in-regions
//@skip-check undefined-function-or-procedure
//@skip-check wrong-string-literal-content

// #Use "./internal"
#Region Internal

Procedure GetBinaryData(Value) Export

    If Value = Undefined Then
        Return;
    EndIf;

    Try

        If TypeOf(Value) = Type("BinaryData") Then
            Return;
        Else

            File = New File(Value);

            If File.Exists() Then
                Value = New BinaryData(Value);
            ElsIf StrFind(Value, "//") Then
                Value = OPI_Tools.Get(Value);
            Else
                Value = Base64Value(Value);
            EndIf;

        EndIf;

    Except
        Raise "Error getting binary data from parameter: " + ErrorDescription();
    EndTry;

EndProcedure

Procedure GetBinaryOrStream(Value) Export

    If Value = Undefined Then
        Return;
    EndIf;

    If TypeOf(Value) <> Type("String") Then
        GetBinaryData(Value);
        Return;
    EndIf;

    File = New File(Value);

    If File.Exists() Then
        Value = New FileStream(Value, FileOpenMode.Open);
    Else
        GetBinaryData(Value);
    EndIf;

EndProcedure

Procedure GetCollection(Value) Export

    If Value = Undefined Then
        Return;
    EndIf;

    Try

        InitialValue = Value;

        If ThisIsCollection(Value) Then
            Return;
        Else

            If TypeOf(Value) = Type("BinaryData") Then
                Value        = GetStringFromBinaryData(Value);
            Else
                Value        = OPI_Tools.NumberToString(Value);
            EndIf;

            File       = New File(Value);
            JSONReader = New JSONReader;

            If File.Exists() Then

                JSONReader.OpenFile(Value);

            ElsIf StrStartsWith(Lower(Value), "http") Then

                TFN = GetTempFileName();
                FileCopy(Value, TFN);
                JSONReader.OpenFile(TFN);
                JSONReader.Read();

                DeleteFiles(TFN);

            Else

                JSONReader.SetString(TrimAll(Value));

            EndIf;

            Value = ReadJSON(JSONReader, True, Undefined, JSONDateFormat.ISO);
            JSONReader.Close();

            If (Not ThisIsCollection(Value)) Or Not ValueIsFilled(Value) Then

                Value = InitialValue;
                GetArray(Value);

            EndIf;

        EndIf;

    Except

        Value = InitialValue;
        GetArray(Value);

    EndTry;

EndProcedure

Procedure GetArray(Value) Export

    If TypeOf(Value) = Type("Array") Then
        Return;
    EndIf;

    If TypeOf(Value) = Type("String") And StrStartsWith(Value, "[") And StrEndsWith(Value, "]") Then

        CommaInQuotes = "','";

        Value = StrReplace(Value, "['"   , "");
        Value = StrReplace(Value, "']"   , "");
        Value = StrReplace(Value, "', '" , CommaInQuotes);
        Value = StrReplace(Value, "' , '", CommaInQuotes);
        Value = StrReplace(Value, "' ,'" , CommaInQuotes);

        Value = StrSplit(Value, CommaInQuotes, False);

        For N = 0 To Value.UBound() Do

            Value[N] = TrimAll(Value[N]);

        EndDo;

    Else

        If TypeOf(Value) = Type("Number") Then
            Value        = OPI_Tools.NumberToString(Value);
        EndIf;

        OPI_Tools.ValueToArray(Value);

    EndIf;

EndProcedure

Procedure GetBoolean(Value) Export

    If Value = Undefined Then
        Return;
    EndIf;

    Try

        If TypeOf(Value) = Type("Boolean") Then

            Return;

        Else

            Value = Boolean(Value);

        EndIf;

    Except
        Raise "Error getting boolean data from parameter";
    EndTry;

EndProcedure

Procedure GetLine(Value, Val FromSource = False) Export

    If Value = Undefined Then
        Return;
    EndIf;

    Try

        If ThisIsSymbolic(Value) Then

            If Not FromSource Then
                Value = OPI_Tools.NumberToString(Value);
                Return;
            EndIf;

            Value = OPI_Tools.NumberToString(Value);
            File  = New File(Value);

            If File.Exists() Then

                TextReader = New TextReader(Value);
                Value      = TextReader.Read();
                TextReader.Close();

            ElsIf StrStartsWith(Lower(Value), "http") Then

                TFN = GetTempFileName();
                FileCopy(Value, TFN);

                TextReader = New TextReader(TFN);
                Value      = TextReader.Read();
                TextReader.Close();

                DeleteFiles(TFN);

            Else

                Return;

            EndIf;

        ElsIf TypeOf(Value) = Type("BinaryData") Then

            Value = GetStringFromBinaryData(Value);

        ElsIf ThisIsCollection(Value) Then

            Value = OPI_Tools.JSONString(Value);

        Else
            Return;
        EndIf;

    Except
        Value = String(Value);
        Return;
    EndTry;

EndProcedure

Procedure GetDate(Value) Export

    If Value = Undefined Then
        Return;
    EndIf;

    Date = "Date";

    Try

        If TypeOf(Value) = Type(Date) Then

            Return;

        Else

            Value = XMLValue(Type(Date), Value);

        EndIf;

    Except
        OOD   = New TypeDescription(Date);
        Value = OOD.AdjustValue(Value);
    EndTry;

EndProcedure

Procedure GetNumber(Value) Export

    TypeDescription = New TypeDescription("Number");
    Value           = TypeDescription.AdjustValue(Value);

EndProcedure

#EndRegion

#Region Private

Function ThisIsCollection(Val Value)

    Return TypeOf(Value) = Type("Array")
        Or TypeOf(Value) = Type("Structure")
        Or TypeOf(Value) = Type("Map");

EndFunction

Function ThisIsSymbolic(Val Value)

    Return TypeOf(Value) = Type("String")
        Or TypeOf(Value) = Type("Number")
        Or TypeOf(Value) = Type("Date");

EndFunction

#EndRegion
