using System.Runtime.InteropServices;
using System.Text;
using System.Xml.Linq;

#pragma warning disable IDE0130 // Namespace does not match folder structure
namespace ArmaDragonflyClient
#pragma warning restore IDE0130 // Namespace does not match folder structure
{
    public class CallContext
    {
        public ulong SteamId { get; set; }
        public string FileSource { get; set; }
        public string MissionName { get; set; }
        public string ServerName { get; set; }
        public short RemoteExecutedOwner { get; set; }
    }

    public class Main
    {
        private const string ADC_VERSION = "1.0.0";
        public const int ADC_BUFFERSIZE = 10240;
        public static string ADC_HOST {get; private set; } = "127.0.0.1";
        public static int ADC_PORT {get; private set; } = 6379;
        public static string ADC_PASSWORD {get; private set; } = "xyz123";
        public static string ADC_LOGFOLDER {get; private set; } = $"{Path.DirectorySeparatorChar}@dragonfly{Path.DirectorySeparatorChar}logs";
        public static bool ADC_DEBUG {get; private set; } = false;
        public static bool ADC_INITCHECK {get; private set; } = false;
        public static string STEAMID {get; private set; } = "";
        public static bool ADC_CONTEXTLOG {get; private set; } = false;
        public static IntPtr ADC_CONTEXT { get; private set; }
        private static int numCalls = 0;
        public static ExtensionCallback Callback { get; private set; }
        public delegate int ExtensionCallback([MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string function, [MarshalAs(UnmanagedType.LPStr)] string data);


        public static void ADC_Init()
        {
            char[] separator = ['='];
            string[] commandLineArgs = Environment.GetCommandLineArgs();
            string str = "";

            for (int index = 0; index < commandLineArgs.Length; index++)
            {
                string[] strArray = commandLineArgs[index].Split(separator, StringSplitOptions.RemoveEmptyEntries);
                if (strArray[0].Equals("-adc", StringComparison.CurrentCultureIgnoreCase))
                {
                    str = strArray[1];
                    break;
                }
            }

            if (str == "")
                str = $"{Path.DirectorySeparatorChar}@dragonfly{Path.DirectorySeparatorChar}config.xml";

            if (File.Exists(Environment.CurrentDirectory + $"{Path.DirectorySeparatorChar}{str}"))
            {
                List<string> strList = [];
                List<string> list = [.. XElement.Load(Environment.CurrentDirectory + $"{Path.DirectorySeparatorChar}{str}").Elements().Select(eintrag => (string)eintrag)];
                ADC_HOST = list[0];
                ADC_PORT = Convert.ToInt32(list[1]);
                ADC_PASSWORD = list[2];
                if (bool.TryParse(list[3], out bool res1))
                    ADC_CONTEXTLOG = res1;
                if (bool.TryParse(list[4], out bool res2))
                    ADC_DEBUG = res2;

                Log($"Config file found! Context Mode: {ADC_CONTEXTLOG}! Debug Mode: {ADC_DEBUG}! Changed Server Settings to: {ADC_HOST}:{ADC_PORT}:{ADC_PASSWORD}!", "action");
            }
            else
            {
                Log("Config file not found! Default Settings Loaded.", "action");
            }

            ADC_INITCHECK = true;
        }

        public static void Log(string msg, string logType)
        {
            if (!ADC_DEBUG)
                return;
            string logFileName = logType + ".log";
            string path = Environment.CurrentDirectory + ADC_LOGFOLDER;
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            using (StreamWriter streamWriter = new(Path.Combine(path, logFileName), true))
            {
                streamWriter.WriteLine(DateTime.Now.ToString() + " >> " + msg);
            };
        }

        /// <summary>
        /// Called only once when Arma 3 loads the extension.
        /// </summary>
        /// <param name="func">Pointer to Arma 3's callback function</param>
        [UnmanagedCallersOnly(EntryPoint = "RVExtensionRegisterCallback")]
        public unsafe static void RVExtensionRegisterCallback(nint func)
        {
            Callback = (Marshal.GetDelegateForFunctionPointer<ExtensionCallback>(func));
        }

        /// <summary>
        /// Called only once when Arma 3 loads the extension.
        /// The output will be written in the RPT logs.
        /// </summary>
        /// <param name="output">A pointer to the output buffer</param>
        /// <param name="outputSize">The maximum length of the buffer (always 32 for this particular method)</param>
        [UnmanagedCallersOnly(EntryPoint = "RVExtensionVersion")]
#pragma warning disable IDE0060 // Remove unused parameter
        public unsafe static void RVExtensionVersion(char* output, int outputSize)
#pragma warning restore IDE0060 // Remove unused parameter
        {
            WriteOutput(output, ADC_VERSION);
        }

        /// <summary>
        /// Called before every RVExtension/RVExtensionArgs execution, providing context about where the call came from.
        /// </summary>
        /// <param name="argv">
        /// Array of pointers to null-terminated strings containing:
        /// [0] - Steam 64bit UserID
        /// [1] - FileSource
        /// [2] - MissionName
        /// [3] - ServerName
        /// [4] - Machine Network ID
        /// </param>
        /// <param name="argc">Number of arguments in the argv array (always 5).</param>
        [UnmanagedCallersOnly(EntryPoint = "RVExtensionContext")]
        public unsafe static int RVExtensionContext(char** argv, int argc)
        {
            ADC_CONTEXT = (IntPtr)argv;
            STEAMID = Marshal.PtrToStringAnsi((IntPtr)argv[0]);
            string steamID = Marshal.PtrToStringAnsi((IntPtr)argv[0]);
            string fileSource = Marshal.PtrToStringAnsi((IntPtr)argv[1]);
            string missionName = Marshal.PtrToStringAnsi((IntPtr)argv[2]);
            string serverName = Marshal.PtrToStringAnsi((IntPtr)argv[3]);
            short remoteExecutedOwner = short.Parse(Marshal.PtrToStringAnsi((IntPtr)argv[4]));

            if (ADC_CONTEXTLOG)
            {
                Log($"SteamID: {steamID}", "context");
                Log($"FileSource: {fileSource}", "context");
                Log($"MissionName: {missionName}", "context");
                Log($"ServerName: {serverName}", "context");
                Log($"RemoteExecutedOwner: {remoteExecutedOwner}", "context");
            }

            return 100;
        }

        /// <summary>
        /// The entry point for the default "callExtension" command.
        /// </summary>
        /// <param name="output">A pointer to the output buffer</param>
        /// <param name="outputSize">The maximum size of the buffer (20480 bytes)</param>
        /// <param name="function">The function identifier passed in "callExtension"</param>
        [UnmanagedCallersOnly(EntryPoint = "RVExtension")]
#pragma warning disable IDE0060 // Remove unused parameter
        public unsafe static void RVExtension(char* output, int outputSize, char* function)
#pragma warning restore IDE0060 // Remove unused parameter
        {
            if (!ADC_INITCHECK)
                ADC_Init();

            numCalls++;

            var func = GetString(function);
            switch (func.ToLower())
            {
                case "time":
                    DateTime timeNow = DateTime.Now;
                    string formattedTime = timeNow.ToString("dd:MM:yyyy HH:mm:ss");
                    WriteOutput(output, formattedTime);
                    break;
                default:
                    WriteOutput(output, func);
                    break;
            }
        }

        /// <summary>
        /// The entry point for the "callExtension" command with function arguments.
        /// </summary>
        /// <param name="output">A pointer to the output buffer</param>
        /// <param name="outputSize">The maximum size of the buffer (20480 bytes)</param>
        /// <param name="function">The function identifier passed in "callExtension"</param>
        /// <param name="argv">The args passed to "callExtension" as a string array</param>
        /// <param name="argc">Number of elements in "argv"</param>
        /// <returns>The return code</returns>
        [UnmanagedCallersOnly(EntryPoint = "RVExtensionArgs")]
        public unsafe static int RVExtensionArgs(char* output, int outputSize, char* function, char** argv, int argc)
        {
            if (!ADC_INITCHECK)
                ADC_Init();

            numCalls++;

            var func = GetString(function);
            long _id = Utils.GetUniqueId();

            List<string> argsArr = [];
            for (int i = 0; i < argc; i++)
            {
                argsArr.Add(GetString(argv[i]));
            }

            switch (func.ToLower())
            {
                case "get":
                    HandleGetOperation(_id, argsArr, argc);
                    WriteOutput(output, $"[\"{_id}_get\",{argsArr[1]}]");
                    return 100;
                case "set":
                    HandleSetOperation(argsArr);
                    WriteOutput(output, "Async");
                    return 200;
                case "del":
                    HandleDelOperation(argsArr);
                    WriteOutput(output, "Async");
                    return 200;
                case "listadd":
                    HandleListAddOperation(argsArr, argc);
                    WriteOutput(output, "Async");
                    return 200;
                case "listidx":
                    HandleListIdxOperation(_id, argsArr, argc);
                    WriteOutput(output, $"[\"{_id}_listidx\",{argsArr[2]}]");
                    return 100;
                case "listlen":
                    HandleListLenOperation(_id, argsArr);
                    WriteOutput(output, $"[\"{_id}_listlen\"]");
                    return 100;
                case "listrem":
                    HandleListRemOperation(argsArr);
                    WriteOutput(output, "Async");
                    return 200;
                case "listrng":
                    HandleListRngOperation(_id, argsArr, argc);
                    WriteOutput(output, $"[\"{_id}_listrng\",{argsArr[3]}]");
                    return 100;
                case "listset":
                    HandleListSetOperation(argsArr);
                    WriteOutput(output, "Async");
                    return 200;
                case "hset":
                    HandleHSetOperation(argsArr, argc);
                    WriteOutput(output, "Async");
                    return 200;
                case "hsetid":
                    HandleHSetIdOperation(argsArr, argc);
                    WriteOutput(output, "Async");
                    return 200;
                case "hget":
                    HandleHGetOperation(_id, argsArr, argc);
                    WriteOutput(output, $"[\"{_id}_hget\",{argsArr[1]}]");
                    return 100;
                case "hgetid":
                    HandleHGetIdOperation(_id, argsArr, argc);
                    WriteOutput(output, $"[\"{_id}_hgetid\",{argsArr[2]}]");
                    return 100;
                case "hgetall":
                    HandleHGetAllOperation(_id, argsArr, argc);
                    WriteOutput(output, $"[\"{_id}_hgetall\",{argsArr[0]}]");
                    return 100;
                case "hgetallid":
                    HandleHGetAllIdOperation(_id, argsArr, argc);
                    WriteOutput(output, $"[\"{_id}_hgetallid\",{argsArr[1]}]");
                    return 100;
                case "hdel":
                    HandleHDelOperation(argsArr);
                    WriteOutput(output, "Async");
                    return 200;
                case "hdelid":
                    HandleHDelIdOperation(argsArr);
                    WriteOutput(output, "Async");
                    return 200;
                case "publish":
                    HandlePublishOperation(_id, argsArr);
                    WriteOutput(output, $"[\"{_id}_publish\"]");
                    return 100;
                case "subscribe":
                    HandleSubscribeOperation(_id, argsArr, argc);
                    WriteOutput(output, $"[\"{_id}_subscribe\"]");
                    return 100;
                case "savedb":
                    HandleSaveDBOperation();
                    WriteOutput(output, "Async");
                    return 200;
                case "setup":
                    HandleSetupOperation(argsArr, argc);
                    WriteOutput(output, "Connection settings updated");
                    return 100;
                case "version":
                    WriteOutput(output, ADC_VERSION);
                    return 100;
                default:
                    WriteOutput(output, "Available Functions: get, set, del, listadd, listidx, listlen, listrem, listrng, listset, hset, hsetid, hget, hgetid, hgetall, hgetallid, hdel, hdelid, publish, subscribe, savedb, setup, version");
                    return -1;
            }
        }

        /// <summary>
        /// Reads a string from the given pointer. 
        /// If the pointer is null, a default value will be returned instead.
        /// </summary>
        /// <param name="pointer">The pointer to read</param>
        /// <param name="defaultValue">The string's default value</param>
        /// <returns>The marshalled string</returns>
        private unsafe static string GetString(char* pointer, string defaultValue = "")
        {
            return Marshal.PtrToStringAnsi((nint)pointer) ?? defaultValue;
        }

        /// <summary>
        /// Serializes a list of strings into a string representing a valid Arma 3 array.
        /// </summary>
        /// <param name="list">The list of strings to serialize</param>
        /// <returns>A string representing an Arma 3 array</returns>
        private static string SerializeList(List<string> list)
        {
            var content = string.Join(",", [.. list]);
            return string.Format("[{0}]", content);
        }

        /// <summary>
        /// Writes the given payload to the output buffer using the provided pointer.
        /// Ensures that the payload string is always null terminated.
        /// </summary>
        /// <param name="output">A pointer to the output buffer</param>
        /// <param name="payload">The payload to write</param>
        private unsafe static void WriteOutput(char* output, string payload)
        {
            byte[] bytes = Encoding.ASCII.GetBytes(payload + '\0');
            Marshal.Copy(bytes, 0, (nint)output, bytes.Length);
        }

        private static void HandleGetOperation(long _id, List<string> argsArr, int argsCnt)
        {
            Task.Run(async () =>
            {
                string _uniqueID = $"{_id}_get";
                switch (argsCnt)
                {
                    case 2:
                        await DragonflyDB.DragonflyGetAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID);
                        break;
                    case 3:
                        await DragonflyDB.DragonflyGetAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID, argsArr[2].Trim('"'));
                        break;
                    case 4:
                        await DragonflyDB.DragonflyGetAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID, argsArr[2].Trim('"'), argsArr[3].Trim('"'));
                        break;
                }
            });
        }

        private static void HandleSetOperation(List<string> argsArr)
        {
            Task.Run(async () =>
            {
                await DragonflyDB.DragonflySetAsync(argsArr[0].Trim('"'), argsArr[1]);
            });
        }

        private static void HandleDelOperation(List<string> argsArr)
        {
            Task.Run(async () =>
            {
                await DragonflyDB.DragonflyDeleteAsync(argsArr[0].Trim('"'));
            });
        }

        private static void HandleListAddOperation(List<string> argsArr, int argsCnt)
        {
            Task.Run(async () =>
            {
                switch (argsCnt)
                {
                    case > 2:
                        for (var i = 0; i < argsCnt; i++)
                        {
                            await DragonflyDB.DragonflyListAddAsync(argsArr[0].Trim('"'), argsArr[i]);
                        }
                        break;
                    default:
                        await DragonflyDB.DragonflyListAddAsync(argsArr[0].Trim('"'), argsArr[1]);
                        break;
                }
            });
        }

        private static void HandleListIdxOperation(long _id, List<string> argsArr, int argsCnt)
        {
            Task.Run(async () =>
            {
                string _uniqueID = $"{_id}_listidx";
                switch (argsCnt)
                {
                    case 3:
                        await DragonflyDB.DragonflyListIndexAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), _uniqueID);
                        break;
                    case 4:
                        await DragonflyDB.DragonflyListIndexAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), _uniqueID, argsArr[3].Trim('"'));
                        break;
                    case 5:
                        await DragonflyDB.DragonflyListIndexAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), _uniqueID, argsArr[3].Trim('"'), argsArr[4].Trim('"'));
                        break;
                }
            });
        }

        private static void HandleListLenOperation(long _id, List<string> argsArr)
        {
            Task.Run(async () =>
            {
                string _uniqueID = $"{_id}_listlen";
                await DragonflyDB.DragonflyListLengthAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID);
            });
        }

        private static void HandleListRngOperation(long _id, List<string> argsArr, int argsCnt)
        {
            Task.Run(async () =>
            {
                string _uniqueID = $"{_id}_listrng";
                switch (argsCnt)
                {
                    case 4:
                        await DragonflyDB.DragonflyListRangeAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), argsArr[3].Trim('"'), _uniqueID);
                        break;
                    case 5:
                        await DragonflyDB.DragonflyListRangeAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), argsArr[3].Trim('"'), _uniqueID, argsArr[4].Trim('"'));
                        break;
                    case 6:
                        await DragonflyDB.DragonflyListRangeAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), argsArr[3].Trim('"'), _uniqueID, argsArr[4].Trim('"'), argsArr[5].Trim('"'));
                        break;
                }
            });
        }

        private static void HandleListRemOperation(List<string> argsArr)
        {
            Task.Run(async () =>
            {
                await DragonflyDB.DragonflyListRemoveAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'));
            });
        }

        private static void HandleListSetOperation(List<string> argsArr)
        {
            Task.Run(async () =>
            {
                await DragonflyDB.DragonflyListSetAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2]);
            });
        }

        private static void HandleHSetOperation(List<string> argsArr, int argsCnt)
        {
            Task.Run(async () =>
            {
                switch (argsCnt)
                {
                    case > 2:
                        for (var i = 0; i < argsCnt; i += 2)
                        {
                            await DragonflyDB.DragonflyHashSetAsync(STEAMID, argsArr[i].Trim('"'), argsArr[i + 1]);
                        }
                        break;
                    default:
                        await DragonflyDB.DragonflyHashSetAsync(STEAMID, argsArr[0].Trim('"'), argsArr[1]);
                        break;
                }
            });
        }

        private static void HandleHSetIdOperation(List<string> argsArr, int argsCnt)
        {
            Task.Run(async () => {
                switch (argsCnt)
                {
                    case > 4:
                        for (var i = 1; i < argsCnt; i += 2)
                        {
                            await DragonflyDB.DragonflyHashSetAsync(argsArr[0].Trim('"'), argsArr[i].Trim('"'), argsArr[i + 1]);
                        }
                        break;
                    default:
                        await DragonflyDB.DragonflyHashSetAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2]);
                        break;
                }
            });
        }

        private static void HandleHGetOperation(long _id, List<string> argsArr, int argsCnt)
        {
            Task.Run(async () =>
            {
                string _uniqueID = $"{_id}_hget";
                switch (argsCnt)
                {
                    case 2:
                        await DragonflyDB.DragonflyHashGetAsync(STEAMID, argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID);
                        break;
                    case 3:
                        await DragonflyDB.DragonflyHashGetAsync(STEAMID, argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID, argsArr[2].Trim('"'));
                        break;
                    case 4:
                        await DragonflyDB.DragonflyHashGetAsync(STEAMID, argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID, argsArr[2].Trim('"'), argsArr[3].Trim('"'));
                        break;
                }
            });
        }

        private static void HandleHGetIdOperation(long _id, List<string> argsArr, int argsCnt)
        {
            Task.Run(async () =>
            {
                string _uniqueID = $"{_id}_hgetid";
                switch (argsCnt)
                {
                    case 3:
                        await DragonflyDB.DragonflyHashGetAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), _uniqueID);
                        break;
                    case 4:
                        await DragonflyDB.DragonflyHashGetAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), _uniqueID, argsArr[3].Trim('"'));
                        break;
                    case 5:
                        await DragonflyDB.DragonflyHashGetAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), _uniqueID, argsArr[3].Trim('"'), argsArr[4].Trim('"'));
                        break;
                }
            });
        }

        private static void HandleHGetAllOperation(long _id, List<string> argsArr, int argsCnt)
        {
            Task.Run(async () =>
            {
                string _uniqueID = $"{_id}_hgetall";
                switch (argsCnt)
                {
                    case 1:
                        await DragonflyDB.DragonflyHashGetAllAsync(STEAMID, argsArr[0].Trim('"'), _uniqueID);
                        break;
                    case 2:
                        await DragonflyDB.DragonflyHashGetAllAsync(STEAMID, argsArr[0].Trim('"'), _uniqueID, argsArr[1].Trim('"'));
                        break;
                    case 3:
                        await DragonflyDB.DragonflyHashGetAllAsync(STEAMID, argsArr[0].Trim('"'), _uniqueID, argsArr[1].Trim('"'), argsArr[2].Trim('"'));
                        break;
                }
            });
        }

        private static void HandleHGetAllIdOperation(long _id, List<string> argsArr, int argsCnt)
        {
            Task.Run(async () =>
            {
                string _uniqueID = $"{_id}_hgetallid";
                switch (argsCnt)
                {
                    case 2:
                        await DragonflyDB.DragonflyHashGetAllAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID);
                        break;
                    case 3:
                        await DragonflyDB.DragonflyHashGetAllAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID, argsArr[2].Trim('"'));
                        break;
                    case 4:
                        await DragonflyDB.DragonflyHashGetAllAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID, argsArr[2].Trim('"'), argsArr[3].Trim('"'));
                        break;
                }
            });
        }

        private static void HandleHDelOperation(List<string> argsArr)
        {
            Task.Run(async () =>
            {
                await DragonflyDB.DragonflyHashDeleteAsync(STEAMID, argsArr[0].Trim('"'));
            });
        }

        private static void HandleHDelIdOperation(List<string> argsArr)
        {
            Task.Run(async () =>
            {
                await DragonflyDB.DragonflyHashDeleteAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'));
            });
        }

        private static void HandleSaveDBOperation()
        {
            Task.Run(DragonflyDB.DragonflySaveDBAsync);
        }

        private static void HandleSetupOperation(List<string> argsArr, int argsCnt)
        {
            if (argsCnt != 3)
            {
                Log("Invalid number of arguments for 'setup' function", "error");
                return;
            }

            string host = argsArr[0].Trim('"');

            if (!int.TryParse(argsArr[1].Trim('"'), out int port))
            {
                Log("Invalid port number", "error");
                return;
            }

            string password = argsArr[2].Trim('"');
            if (string.IsNullOrEmpty(password))
            {
                Log("Warning: Setting up DragonflyDB without authentication is not recommended", "action");
                password = "";
            }

            ADC_HOST = host;
            ADC_PORT = port;
            ADC_PASSWORD = password;

            Log($"DragonflyDB connection settings updated - Host: '{host}', Port: '{port}', Password: '{password}'", "action");
        }

        private static void HandlePublishOperation(long _id, List<string> argsArr)
        {
            Task.Run(async () =>
            {
                string _uniqueID = $"{_id}_publish";
                await DragonflyDB.DragonflyPublishAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), _uniqueID);
            });
        }

        private static void HandleSubscribeOperation(long _id, List<string> argsArr, int argsCnt)
        {
            Task.Run(async () =>
            {
                string _uniqueID = $"{_id}_subscribe";
                switch (argsCnt)
                {
                    case 3:
                        await DragonflyDB.DragonflySubscribeAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), _uniqueID);
                        break;
                    case 4:
                        await DragonflyDB.DragonflySubscribeAsync(argsArr[0].Trim('"'), argsArr[1].Trim('"'), argsArr[2].Trim('"'), _uniqueID, argsArr[3].Trim('"'));
                        break;
                }
            });
        }
    }
}