using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
using Adaptation.Ifx.Eaf.Common.Configuration;
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
using Adaptation.Shared.Methods;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shared.PasteSpecialXml.EAF.XML.API.CellInstance;
using Shared.PasteSpecialXml.EAF.XML.API.ConfigurationData;
using Shared.PasteSpecialXml.EAF.XML.API.EquipmentDictionary;
using Shared.PasteSpecialXml.EAF.XML.API.EquipmentType;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace Shared;

public class AdaptationTesting : ISMTP
{

    protected readonly string _Environment;
    protected readonly string _HostNameAndPort;
    protected readonly TestContext _TestContext;
    protected readonly bool _SkipEquipmentDictionary;
    protected readonly Dictionary<string, CellInstanceVersion> _CellInstanceVersions;
    protected readonly Dictionary<string, EquipmentTypeVersion> _EquipmentTypeVersions;
    protected readonly Dictionary<string, string> _ParameterizedModelObjectDefinitionTypes;
    protected readonly Dictionary<string, EquipmentDictionaryVersion> _EquipmentDictionaryVersions;
    protected readonly Dictionary<string, FileConnectorConfiguration> _FileConnectorConfigurations;
    protected readonly Dictionary<string, IList<ModelObjectParameterDefinition>> _ModelObjectParameters;
    protected readonly Dictionary<string, List<Tuple<string, string>>> _EquipmentDictionaryEventDescriptions;

    public string Environment => _Environment;
    public TestContext TestContext => _TestContext;
    public string HostNameAndPort => _HostNameAndPort;
    public bool SkipEquipmentDictionary => _SkipEquipmentDictionary;
    public Dictionary<string, CellInstanceVersion> CellInstanceVersions => _CellInstanceVersions;
    public Dictionary<string, EquipmentTypeVersion> EquipmentTypeVersions => _EquipmentTypeVersions;
    public Dictionary<string, IList<ModelObjectParameterDefinition>> ModelObjectParameters => _ModelObjectParameters;
    public Dictionary<string, EquipmentDictionaryVersion> EquipmentDictionaryVersions => _EquipmentDictionaryVersions;
    public Dictionary<string, FileConnectorConfiguration> FileConnectorConfigurations => _FileConnectorConfigurations;
    public Dictionary<string, string> ParameterizedModelObjectDefinitionTypes => _ParameterizedModelObjectDefinitionTypes;
    public Dictionary<string, List<Tuple<string, string>>> EquipmentDictionaryEventDescriptions => _EquipmentDictionaryEventDescriptions;

    void ISMTP.SendLowPriorityEmailMessage(string subject, string body) => throw new NotImplementedException();

    void ISMTP.SendHighPriorityEmailMessage(string subject, string body) => throw new NotImplementedException();

    void ISMTP.SendNormalPriorityEmailMessage(string subject, string body) => throw new NotImplementedException();

    public AdaptationTesting(TestContext testContext, bool skipEquipmentDictionary)
    {

        string environment = GetEnvironment(testContext);
        string hostNameAndPort = GetHostNameAndPort(environment);
        _TestContext = testContext;
        _Environment = environment;
        _HostNameAndPort = hostNameAndPort;
        _SkipEquipmentDictionary = skipEquipmentDictionary;
        _CellInstanceVersions = new Dictionary<string, CellInstanceVersion>();
        _EquipmentTypeVersions = new Dictionary<string, EquipmentTypeVersion>();
        _ParameterizedModelObjectDefinitionTypes = new Dictionary<string, string>();
        _EquipmentDictionaryVersions = new Dictionary<string, EquipmentDictionaryVersion>();
        _FileConnectorConfigurations = new Dictionary<string, FileConnectorConfiguration>();
        _ModelObjectParameters = new Dictionary<string, IList<ModelObjectParameterDefinition>>();
        _EquipmentDictionaryEventDescriptions = new Dictionary<string, List<Tuple<string, string>>>();
    }

    protected static string GetEnvironment(TestContext testContext)
    {
        string result = testContext.TestName.Split('_')[0];
        return result;
    }

    protected static string GetHostNameAndPort(string environment)
    {
        string result;
        result = environment switch
        {
            "LocalHost" => "localhost:9003",
            "Development" => "eaf-dev.mes.infineon.com:9003",
            "Staging" => "eaf-staging.mes.infineon.com:9003",
            "Production" => "eaf-prod.mes.infineon.com:9003",
            _ => throw new Exception(),
        };
        return result;
    }

    protected string GetTestResultsDirectory()
    {
        string result = string.Empty;
        string testResults = "05_TestResults";
        string checkDirectory = _TestContext.TestResultsDirectory;
        if (string.IsNullOrEmpty(checkDirectory) || !checkDirectory.Contains(testResults))
            throw new Exception();
        string rootDirectory = Path.GetPathRoot(checkDirectory);
        for (int i = 0; i < int.MaxValue; i++)
        {
            checkDirectory = Path.GetDirectoryName(checkDirectory);
            if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == rootDirectory)
                break;
            if (checkDirectory.EndsWith(testResults) && Directory.Exists(checkDirectory))
            {
                result = checkDirectory;
                break;
            }
        }
        if (string.IsNullOrEmpty(result))
            throw new Exception();
        return result;
    }

    protected static string GetCellInstanceConnectionName(string cellInstanceConnectionName)
    {
        string result;
        if (string.IsNullOrEmpty(cellInstanceConnectionName) || cellInstanceConnectionName[cellInstanceConnectionName.Length - 1] != '_')
            result = cellInstanceConnectionName;
        else
        {
            bool check = false;
            List<char> chars = new();
            StringBuilder stringBuilder = new();
            for (int i = cellInstanceConnectionName.Length - 1; i > -1; i--)
            {
                if (!check && cellInstanceConnectionName[i] != '_')
                    check = true;
                else if (!check && cellInstanceConnectionName[i] == '_')
                    chars.Add('-');
                if (check)
                    chars.Add(cellInstanceConnectionName[i]);
            }
            for (int i = chars.Count - 1; i > -1; i--)
                _ = stringBuilder.Append(chars[i]);
            result = stringBuilder.ToString();
        }
        return result;
    }

    private static string GetMethodBaseNameWithActualCICN(string methodBaseName, string cellInstanceName, string cellInstanceConnectionNameFromMethodBaseName, string cellInstanceConnectionName, string ticks)
    {
        string results;
        if (string.IsNullOrEmpty(cellInstanceConnectionNameFromMethodBaseName) || string.IsNullOrEmpty(cellInstanceConnectionName))
            results = methodBaseName;
        else if (cellInstanceConnectionNameFromMethodBaseName.Length != cellInstanceConnectionName.Length)
            throw new Exception();
        else
        {
            string[] segments = methodBaseName.Split(new string[] { cellInstanceName }, StringSplitOptions.None);
            if (segments.Length == 2)
                results = methodBaseName.Replace(cellInstanceConnectionNameFromMethodBaseName, cellInstanceConnectionName);
            else if (segments.Length != 3)
                throw new Exception();
            else if (string.IsNullOrEmpty(ticks))
                results = string.Concat(segments[0], cellInstanceName, segments[1], cellInstanceConnectionName);
            else if (!segments[2].Contains(ticks))
                throw new Exception();
            else
                results = string.Concat(segments[0], cellInstanceName, segments[1], cellInstanceConnectionName, ticks, segments[2].Split(new string[] { ticks }, StringSplitOptions.None)[1]);
        }
        if (methodBaseName.Length != results.Length)
            throw new Exception();
        return results;
    }

    internal string[] GetSegments(string methodBaseName)
    {
        List<string> results;
        string fileFullName;
        string comment;
        string[] textFiles;
        string seperator = "__";
        string connectionNameAndTicks;
        string cellInstanceConnectionName;
        string ticks = DateTime.Now.Ticks.ToString();
        string cellInstanceConnectionNameFromMethodBaseName;
        string testResultsDirectory = GetTestResultsDirectory();
        string[] segments = methodBaseName.Split(new string[] { seperator }, StringSplitOptions.None);
        if (segments[0] != _Environment)
            throw new Exception();
        string rawVersionName = segments[1];
        string rawCellInstanceName = segments[2];
        string cellInstanceVersionName = segments[1].Replace('_', '.');
        string cellInstanceName = segments[2].Replace('_', '-').Replace("_EQPT", "-EQPT");
        string before = string.Concat(_Environment, seperator, rawVersionName, seperator, cellInstanceName, seperator);
        string after = methodBaseName.Substring(before.Length);
        string versionDirectory = Path.Combine(testResultsDirectory, _Environment, cellInstanceName, cellInstanceVersionName);
        if (!Directory.Exists(versionDirectory))
            _ = Directory.CreateDirectory(versionDirectory);
        comment = segments[segments.Length - 1];
        if (after.Length < ticks.Length || after == comment)
        {
            ticks = string.Empty;
            cellInstanceConnectionNameFromMethodBaseName = string.Empty;
        }
        else
        {
            connectionNameAndTicks = after.Substring(0, after.Length - 2 - comment.Length);
            if (connectionNameAndTicks.Length - ticks.Length < 1)
            {
                ticks = string.Empty;
                cellInstanceConnectionNameFromMethodBaseName = string.Empty;
            }
            else
            {
                cellInstanceConnectionNameFromMethodBaseName = connectionNameAndTicks.Substring(0, connectionNameAndTicks.Length - ticks.Length);
                ticks = connectionNameAndTicks.Substring(cellInstanceConnectionNameFromMethodBaseName.Length);
            }
        }
        if (string.IsNullOrEmpty(ticks) || string.IsNullOrEmpty(cellInstanceConnectionNameFromMethodBaseName) || !long.TryParse(ticks, out _))
        {
            ticks = string.Empty;
            comment = string.Empty;
            cellInstanceConnectionNameFromMethodBaseName = after;
        }
        cellInstanceConnectionName = GetCellInstanceConnectionName(cellInstanceConnectionNameFromMethodBaseName);
        string methodBaseNameWithActualCICN = GetMethodBaseNameWithActualCICN(methodBaseName, rawCellInstanceName, cellInstanceConnectionNameFromMethodBaseName, cellInstanceConnectionName, ticks);
        if (string.IsNullOrEmpty(ticks))
        {
            textFiles = Array.Empty<string>();
            fileFullName = Path.Combine(versionDirectory, methodBaseNameWithActualCICN, $"{cellInstanceConnectionNameFromMethodBaseName}.json");
        }
        else
        {
            segments = methodBaseNameWithActualCICN.Split(new string[] { ticks }, StringSplitOptions.None);
            string textDirectory = Path.Combine(versionDirectory, segments[0], string.Concat(ticks, segments[1]));
            fileFullName = Path.Combine(versionDirectory, segments[0], $"{cellInstanceConnectionNameFromMethodBaseName}.json");
            if (!Directory.Exists(textDirectory))
            {
                textFiles = Array.Empty<string>();
                string renameDirectory = Path.Combine(Path.GetDirectoryName(textDirectory), $"_Rename - {Path.GetFileName(textDirectory)}");
                _ = Directory.CreateDirectory(renameDirectory);
                _ = Process.Start("explorer.exe", renameDirectory);
                File.WriteAllText(Path.Combine(renameDirectory, $"{nameof(FileConnectorConfiguration.SourceFileFilter)}.txt"), string.Empty);
                File.WriteAllText(Path.Combine(renameDirectory, $"{nameof(FileConnectorConfiguration.SourceFileLocation)}.txt"), string.Empty);
            }
            else
            {
                textFiles = Directory.GetFiles(textDirectory, "*.txt", SearchOption.TopDirectoryOnly);
                if (!textFiles.Any())
                {
                    _ = Process.Start("explorer.exe", textDirectory);
                    File.WriteAllText(Path.Combine(textDirectory, "_ Why.why"), string.Empty);
                }
            }
        }
        results = new List<string>
            {
                _Environment,
                rawCellInstanceName,
                cellInstanceName,
                cellInstanceVersionName,
                cellInstanceConnectionNameFromMethodBaseName,
                cellInstanceConnectionName,
                ticks,
                comment,
                fileFullName
            };
        results.AddRange(textFiles);
        return results.ToArray();
    }

    internal string[] GetSegments(MethodBase methodBase)
    {
        string[] results = GetSegments(methodBase.Name);
        return results;
    }

    internal static string GetEnvironment(string[] segments) => segments[0];

    internal static string GetRawCellInstanceName(string[] segments) => segments[1];

    internal static string GetCellInstanceName(string[] segments) => segments[2];

    internal static string GetCellInstanceVersionName(string[] segments) => segments[3];

    internal static string GetCellInstanceConnectionNameFromMethodBaseName(string[] segments) => segments[4];

    internal static string GetCellInstanceConnectionName(string[] segments) => segments[5];

    internal static string GetTicks(string[] segments) => segments[6];

    internal static string GetComment(string[] segments) => segments[7];

    internal static FileInfo GetFileName(string[] segments) => new(segments[8]);

    internal static string[] GetTextFiles(string[] segments)
    {
        List<string> results = new();
        if (segments.Length > 8)
        {
            for (int i = 9; i < segments.Length; i++)
                results.Add(segments[i]);
        }
        return results.ToArray();
    }

    protected static Stream ToStream(string @this)
    {
        MemoryStream memoryStream = new();
        StreamWriter streamWriter = new(memoryStream);
        streamWriter.Write(@this);
        streamWriter.Flush();
        memoryStream.Position = 0;
        return memoryStream;
    }

    internal static T ParseXML<T>(string @this, bool throwExceptions) where T : class
    {
        object result = null;
        try
        {
            Stream stream = ToStream(@this.Trim());
            XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
            XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes());
            result = xmlSerializer.Deserialize(xmlReader);
            stream.Dispose();
        }
        catch (Exception)
        {
            if (throwExceptions)
                throw;
        }
        return result as T;
    }

    protected static CellInstanceVersion GetCellInstanceVersion(string url)
    {
        CellInstanceVersion result;
        byte[] byteArray;
        ConfigurationData configurationData;
        string decodedCellInstanceConfigurationData;
        string xml;
        try
        {
            xml = XDocument.Load(url).ToString();
        }
        catch (System.Exception exception)
        {
            throw new Exception(string.Concat(url, System.Environment.NewLine, exception.Message));
        }
        configurationData = ParseXML<ConfigurationData>(xml, throwExceptions: true);
        byteArray = Convert.FromBase64String(configurationData.Data);
        decodedCellInstanceConfigurationData = Encoding.Unicode.GetString(byteArray);
        if (xml.Length <= 41)
            throw new Exception(string.Concat("xml isn't valid {", xml, "}"));
        decodedCellInstanceConfigurationData = decodedCellInstanceConfigurationData.Substring(41).Replace("i:type", "i___type");
        result = ParseXML<CellInstanceVersion>(decodedCellInstanceConfigurationData, throwExceptions: true);
        return result;
    }

    protected Tuple<string, CellInstanceVersion> GetCellInstanceVersionTuple(string cellInstanceName, string cellInstanceVersionName)
    {
        Tuple<string, CellInstanceVersion> result;
        CellInstanceVersion cellInstanceVersion;
        string cellInstanceServiceV2 = string.Concat("http://", _HostNameAndPort, "/CellInstanceServiceV2/", cellInstanceName, "/", cellInstanceVersionName, "/configuration");
        if (_CellInstanceVersions.ContainsKey(cellInstanceServiceV2))
            cellInstanceVersion = _CellInstanceVersions[cellInstanceServiceV2];
        else
        {
            cellInstanceVersion = GetCellInstanceVersion(cellInstanceServiceV2);
            _CellInstanceVersions.Add(cellInstanceServiceV2, cellInstanceVersion);
        }
        result = new Tuple<string, CellInstanceVersion>(cellInstanceServiceV2, cellInstanceVersion);
        return result;
    }

    protected static Dictionary<string, int[]> GetComponentModelComponentsIndexes(CellInstanceVersion cellInstanceVersion, string cellInstanceConnectionName)
    {
        Dictionary<string, int[]> results = new();
        ComponentsCellComponent componentsCellComponent;
        if (cellInstanceVersion.ComponentModel.Components is not null)
        {
            for (int i = 0; i < cellInstanceVersion.ComponentModel.Components.Length; i++)
            {
                componentsCellComponent = cellInstanceVersion.ComponentModel.Components[i];
                for (int j = 0; j < componentsCellComponent.Children.Length; j++)
                {
                    if (string.IsNullOrEmpty(componentsCellComponent.Children[j].Equipment.Name))
                        continue;
                    results.Add(componentsCellComponent.Children[j].Name, new int[] { i, j });
                }
            }
        }
        if (!results.Any() || (!string.IsNullOrEmpty(cellInstanceConnectionName) && !results.ContainsKey(cellInstanceConnectionName)))
            throw new Exception("Match not found (check test method name matches Mango)!");
        return results;
    }

    protected static int[] GetCellInstanceConnectionNameIndexes(string cellInstanceConnectionName, Dictionary<string, int[]> componentModelComponentsIndexes)
    {
        int[] result;
        if (string.IsNullOrEmpty(cellInstanceConnectionName))
            result = componentModelComponentsIndexes.ElementAt(0).Value;
        else
        {
            if (componentModelComponentsIndexes is null || !componentModelComponentsIndexes.ContainsKey(cellInstanceConnectionName))
                throw new Exception();
            result = componentModelComponentsIndexes[cellInstanceConnectionName];
        }
        return result;
    }

    protected string[] GetCSharpTextB(FileInfo fileInfo, string cellInstanceName, string cellInstanceVersionName, CellInstanceVersion cellInstanceVersion)
    {
        List<string> results = new();
        string check;
        string loopName;
        string equipmentTypeName;
        string methodName = string.Empty;
        string extractText = string.Empty;
        StringBuilder stringBuilder = new();
        string createSelfDescriptionText = string.Empty;
        List<string> componentsCellComponentCellComponentEquipmentNames = new();
        string cellInstanceNameWithoutHyphen = cellInstanceName.Replace('-', '_');
        ComponentsCellComponentCellComponent componentsCellComponentCellComponent;
        List<string> componentsCellComponentCellComponentEquipmentTypeNames = new();
        string cellInstanceVersionNameAsCode = cellInstanceVersionName.Replace('.', '_');
        List<string> componentsCellComponentCellComponentEquipmentDictionaryNames = new();
        const string sourceDirectoryCloaking = nameof(FileConnectorConfiguration.SourceDirectoryCloaking);
        for (int i = 1; i < 3; i++)
        {
            if (i == 2)
                loopName = "Extract";
            else if (i == 1)
                loopName = "CreateSelfDescription";
            else
                throw new Exception();
            _ = stringBuilder.
                AppendLine("using Adaptation.Shared.Methods;").
                AppendLine("using Microsoft.Extensions.Logging;").
                AppendLine("using Microsoft.VisualStudio.TestTools.UnitTesting;").
                AppendLine("using Shared;").
                AppendLine("using System;").
                AppendLine("using System.Collections.Generic;").
                AppendLine("using System.Diagnostics;").
                AppendLine("using System.IO;").
                AppendLine("using System.Reflection;").
                AppendLine("using System.Text.Json;").
                AppendLine("using System.Threading;");
            _ = stringBuilder.AppendLine().
                Append("namespace _Tests.").Append(loopName).Append('.').Append(_Environment).Append('.').Append(cellInstanceVersionNameAsCode).AppendLine(";").
                AppendLine().
                AppendLine("[TestClass]");
            if (i == 2)
                _ = stringBuilder.
                    Append("public class ").AppendLine(cellInstanceNameWithoutHyphen).
                    AppendLine("{").
                    AppendLine().
                    AppendLine("#pragma warning disable CA2254").
                    AppendLine("#pragma warning disable IDE0060").
                    AppendLine().
                    Append("private static CreateSelfDescription.").Append(_Environment).Append('.').Append(cellInstanceVersionNameAsCode).Append('.').Append(cellInstanceNameWithoutHyphen).Append(" _").Append(cellInstanceNameWithoutHyphen).AppendLine(";");
            else if (i == 1)
                _ = stringBuilder.
                    Append("public class ").Append(cellInstanceNameWithoutHyphen).AppendLine(" : EAFLoggingUnitTesting").
                    AppendLine("{").
                    AppendLine().
                    AppendLine("#pragma warning disable CA2254").
                    AppendLine("#pragma warning disable IDE0060").
                    AppendLine().
                    Append("internal static ").Append(cellInstanceNameWithoutHyphen).AppendLine(" EAFLoggingUnitTesting { get; private set; }");
            else
                throw new Exception();
            if (i == 2)
                _ = stringBuilder.AppendLine();
            else if (i == 1)
                _ = stringBuilder.
                    AppendLine().
                    Append("public ").Append(cellInstanceNameWithoutHyphen).AppendLine("() : base(testContext: null, declaringType: null, skipEquipmentDictionary: false)").
                    AppendLine("{").
                    AppendLine("if (EAFLoggingUnitTesting is null)").
                    AppendLine("throw new Exception();").
                    AppendLine("}").
                    AppendLine().
                    Append("public ").Append(cellInstanceNameWithoutHyphen).AppendLine("(TestContext testContext) : base(testContext, new StackFrame().GetMethod().DeclaringType, skipEquipmentDictionary: false)").
                    AppendLine("{").
                    AppendLine("}").
                    AppendLine();
            else
                throw new Exception();
            _ = stringBuilder.
                AppendLine("[ClassInitialize]").
                AppendLine("public static void ClassInitialize(TestContext testContext)").
                AppendLine("{");
            if (i == 2)
                _ = stringBuilder.
                    Append("CreateSelfDescription.").Append(_Environment).Append('.').Append(cellInstanceVersionNameAsCode).Append('.').Append(cellInstanceNameWithoutHyphen).AppendLine(".ClassInitialize(testContext);").
                    Append('_').Append(cellInstanceNameWithoutHyphen).Append(" = CreateSelfDescription.").Append(_Environment).Append('.').Append(cellInstanceVersionNameAsCode).Append('.').Append(cellInstanceNameWithoutHyphen).AppendLine(".EAFLoggingUnitTesting;").
                    AppendLine("}");
            else if (i == 1)
                _ = stringBuilder.
                    AppendLine("if (EAFLoggingUnitTesting is null)").
                    Append("EAFLoggingUnitTesting = new ").Append(cellInstanceNameWithoutHyphen).AppendLine("(testContext);").
                    AppendLine("EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(testContext.TestName, \" - ClassInitialize\"));").
                    AppendLine("string[] fileNameAndText = EAFLoggingUnitTesting.AdaptationTesting.GetCSharpText(testContext.TestName);").
                    AppendLine("File.WriteAllText(fileNameAndText[0], fileNameAndText[1]);").
                    AppendLine("File.WriteAllText(fileNameAndText[2], fileNameAndText[3]);").
                    AppendLine("}");
            else
                throw new Exception();
            if (i == 2)
                _ = stringBuilder.AppendLine();
            else if (i == 1)
                _ = stringBuilder.
                    AppendLine().
                    AppendLine("[ClassCleanup()]").
                    AppendLine("public static void ClassCleanup()").
                    AppendLine("{").
                    AppendLine("if (EAFLoggingUnitTesting.Logger is not null)").
                    AppendLine("EAFLoggingUnitTesting.Logger.LogInformation(\"Cleanup\");").
                    AppendLine("if (EAFLoggingUnitTesting is not null)").
                    AppendLine("EAFLoggingUnitTesting.Dispose();").
                    AppendLine("}").
                    AppendLine();
            else
                throw new Exception();
            foreach (ComponentsCellComponent componentsCellComponent in cellInstanceVersion.ComponentModel.Components)
            {
                if (componentsCellComponent.Children.Length != 1)
                    continue;
                componentsCellComponentCellComponent = componentsCellComponent.Children[0];
                if (componentsCellComponentCellComponent.Equipment.EquipmentDictionaries?.CellEquipmentDictionaryReference?.DictionaryName is not null)
                    componentsCellComponentCellComponentEquipmentDictionaryNames.Add(componentsCellComponentCellComponent.Equipment.EquipmentDictionaries?.CellEquipmentDictionaryReference?.DictionaryName);
                componentsCellComponentCellComponentEquipmentNames.Add(componentsCellComponentCellComponent.Equipment.Name);
                componentsCellComponentCellComponentEquipmentTypeNames.Add(componentsCellComponentCellComponent.Equipment.EquipmentType.Name);
                methodName = $"{_Environment}__{cellInstanceVersionNameAsCode}__{cellInstanceNameWithoutHyphen}__{componentsCellComponentCellComponent.Equipment.Name.Replace('-', '_')}";
                if (componentsCellComponentCellComponent?.Equipment?.ConnectionSettings?.Setting is null)
                    check = string.Empty;
                else
                    check = (from l in componentsCellComponentCellComponent.Equipment.ConnectionSettings.Setting where l.Name == sourceDirectoryCloaking select l.Value).FirstOrDefault();
                if (string.IsNullOrEmpty(check))
                    check = componentsCellComponentCellComponent.Equipment.SourceFileFilter;
                if (i == 2)
                {
                    _ = stringBuilder.
                        AppendLine("[TestMethod]").
                        Append("public void ").Append(methodName).Append("() => ").Append('_').Append(cellInstanceNameWithoutHyphen).Append('.').Append(methodName).AppendLine("();");
                }
                else if (i == 1)
                {
                    if (componentsCellComponentCellComponent.Equipment.EquipmentType.Version != cellInstanceVersionName)
                        throw new Exception("Versions should match!");
                    equipmentTypeName = componentsCellComponentCellComponent.Equipment.EquipmentType.Name;
                    _ = stringBuilder.
                        AppendLine("[TestMethod]").
                        Append("public void ").Append(methodName).AppendLine("()").
                        AppendLine("{").
                        Append("string check = \"").Append(check.Split('\\').Last()).AppendLine("\";").
                        AppendLine("MethodBase methodBase = new StackFrame().GetMethod();").
                        AppendLine("EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, \" - Getting configuration\"));").
                        AppendLine("_ = Helpers.Metrology.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting);").
                        AppendLine("EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, \" - Exit\"));").
                        AppendLine("}").
                        AppendLine();
                }
                else
                    throw new Exception();
            }
            _ = stringBuilder.
                AppendLine("}").
                AppendLine();
            if (i == 2)
                extractText = stringBuilder.ToString().Trim();
            else if (i == 1)
                createSelfDescriptionText = stringBuilder.ToString().Trim();
            else
                throw new Exception();
            _ = stringBuilder.Clear();
        }
        if (componentsCellComponentCellComponentEquipmentDictionaryNames.Any() && string.IsNullOrEmpty(cellInstanceVersion.FrozenBy))
        {
            if (!cellInstanceVersion.CellCommunicatingRule.EndsWith(".Communicating") || !(from l in componentsCellComponentCellComponentEquipmentNames where l == cellInstanceVersion.CellCommunicatingRule.Split('.')[0] select true).Any())
                throw new Exception($"{methodName} - CellCommunicatingRule not correct in Mango!");
            if (!cellInstanceVersion.CellNotCommunicatingRule.EndsWith(".NotCommunicating") || !(from l in componentsCellComponentCellComponentEquipmentNames where l == cellInstanceVersion.CellNotCommunicatingRule.Split('.')[0] select true).Any())
                throw new Exception($"{methodName} - CellNotCommunicatingRule not correct in Mango!");
        }
        string versionLevelDirectory = Path.GetDirectoryName(fileInfo.DirectoryName);
        results.Add(Path.Combine(versionLevelDirectory, $"{cellInstanceName}-0-CreateSelfDescription.txt"));
        results.Add(createSelfDescriptionText);
        results.Add(Path.Combine(versionLevelDirectory, $"{cellInstanceName}-1-Extract.txt"));
        results.Add(extractText);
        return results.ToArray();
    }

    protected static FileConnectorConfiguration GetFileConnectorConfiguration(string json, ComponentsCellComponentCellComponent componentsCellComponentCellComponent)
    {
        FileConnectorConfiguration result;
        const string sourceDirectoryCloaking = nameof(FileConnectorConfiguration.SourceDirectoryCloaking);
        JsonSerializerOptions jsonSerializerOptions = new()
        { Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) } };
        json = json.Replace(string.Concat("\"", nameof(FileConnectorConfiguration.ConnectionSettings), "\":"), string.Concat("\"Ignore", nameof(FileConnectorConfiguration.ConnectionSettings), "\":"));
        result = JsonSerializer.Deserialize<FileConnectorConfiguration>(json, jsonSerializerOptions);
        if (string.IsNullOrEmpty(result.SourceFileFilter))
            result.SourceFileFilter = string.Empty;
        if (result.ErrorTargetFileLocation is null)
            result.ErrorTargetFileLocation = string.Empty;
        if (result.SourceFileLocation is null)
            result.SourceFileLocation = string.Empty;
        if (result.TargetFileLocation is null)
            result.TargetFileLocation = string.Empty;
        if (result.FolderAgeCheckIndividualSubFolders is null)
            result.FolderAgeCheckIndividualSubFolders = false;
        result.ConnectionSettings = new List<ConnectionSetting>();
        result.SourceFileFilters = result.SourceFileFilter.Split('|').ToList();
        if (componentsCellComponentCellComponent.Equipment?.ConnectionSettings is not null)
        {
            foreach (Setting setting in componentsCellComponentCellComponent.Equipment.ConnectionSettings.Setting)
                result.ConnectionSettings.Add(new ConnectionSetting(null, null) { Name = setting.Name, Value = setting.Value });
        }
        IEnumerable<ConnectionSetting> sourceDirectoryCloakingCollection = (from l in result.ConnectionSettings where l.Name == sourceDirectoryCloaking select l);
        if (sourceDirectoryCloakingCollection.Any())
            result.SourceDirectoryCloaking = sourceDirectoryCloakingCollection.First().Value;
        else
        {
            result.SourceDirectoryCloaking = string.Empty;
            result.ConnectionSettings.Add(new ConnectionSetting(null, null) { Name = sourceDirectoryCloaking, Value = string.Empty });
        }
        return result;
    }

    protected Tuple<string, FileConnectorConfiguration> GetFileConnectorConfigurationTuple(Tuple<string, CellInstanceVersion> cellInstanceVersionTuple, string cellInstanceConnectionName)
    {
        Tuple<string, FileConnectorConfiguration> result;
        FileConnectorConfiguration fileConnectorConfiguration;
        string cellInstanceServiceV2With = string.Concat(cellInstanceVersionTuple.Item1, '/', cellInstanceConnectionName);
        if (_FileConnectorConfigurations.ContainsKey(cellInstanceServiceV2With))
            fileConnectorConfiguration = _FileConnectorConfigurations[cellInstanceServiceV2With];
        else
        {
            Dictionary<string, int[]> componentModelComponentsIndexes = GetComponentModelComponentsIndexes(cellInstanceVersionTuple.Item2, cellInstanceConnectionName);
            int[] cellInstanceConnectionNameIndexes = GetCellInstanceConnectionNameIndexes(cellInstanceConnectionName, componentModelComponentsIndexes);
            ComponentsCellComponentCellComponent componentsCellComponentCellComponent = cellInstanceVersionTuple.Item2.ComponentModel.Components[cellInstanceConnectionNameIndexes[0]].Children[cellInstanceConnectionNameIndexes[1]];
            string json = JsonSerializer.Serialize(componentsCellComponentCellComponent.Equipment, new JsonSerializerOptions { WriteIndented = true });
            fileConnectorConfiguration = GetFileConnectorConfiguration(json, componentsCellComponentCellComponent);
            _FileConnectorConfigurations.Add(cellInstanceServiceV2With, fileConnectorConfiguration);
        }
        result = new Tuple<string, FileConnectorConfiguration>(cellInstanceServiceV2With, fileConnectorConfiguration);
        return result;
    }

    protected static EquipmentTypeVersion GetEquipmentTypeVersion(string url)
    {
        EquipmentTypeVersion result;
        byte[] byteArray;
        ConfigurationData configurationData;
        string decodedCellInstanceConfigurationData;
        string xml;
        try
        {
            xml = XDocument.Load(url).ToString();
        }
        catch (System.Exception exception)
        {
            throw new Exception(string.Concat(url, System.Environment.NewLine, exception.Message));
        }
        configurationData = ParseXML<ConfigurationData>(xml, throwExceptions: true);
        byteArray = Convert.FromBase64String(configurationData.Data);
        decodedCellInstanceConfigurationData = Encoding.Unicode.GetString(byteArray);
        if (xml.Length <= 41)
            throw new Exception(string.Concat("xml isn't valid {", xml, "}"));
        decodedCellInstanceConfigurationData = decodedCellInstanceConfigurationData.Substring(41).Replace("i:type", "i___type");
        result = ParseXML<EquipmentTypeVersion>(decodedCellInstanceConfigurationData, throwExceptions: true);
        return result;
    }

    protected Tuple<string, string, string, EquipmentTypeVersion> GetEquipmentTypeVersionTuple(CellInstanceVersion cellInstanceVersion, string cellInstanceConnectionName)
    {
        Tuple<string, string, string, EquipmentTypeVersion> result;
        EquipmentTypeVersion equipmentTypeVersion;
        Dictionary<string, int[]> componentModelComponentsIndexes = GetComponentModelComponentsIndexes(cellInstanceVersion, cellInstanceConnectionName);
        int[] cellInstanceConnectionNameIndexes = GetCellInstanceConnectionNameIndexes(cellInstanceConnectionName, componentModelComponentsIndexes);
        ComponentsCellComponentCellComponent componentsCellComponentCellComponent = cellInstanceVersion.ComponentModel.Components[cellInstanceConnectionNameIndexes[0]].Children[cellInstanceConnectionNameIndexes[1]];
        string equipmentTypeServiceV2 = string.Concat("http://", _HostNameAndPort, "/EquipmentTypeServiceV2/", componentsCellComponentCellComponent.Equipment.EquipmentType.Name, "/", componentsCellComponentCellComponent.Equipment.EquipmentType.Version, "/configuration");
        if (_EquipmentTypeVersions.ContainsKey(equipmentTypeServiceV2))
            equipmentTypeVersion = _EquipmentTypeVersions[equipmentTypeServiceV2];
        else
        {
            equipmentTypeVersion = GetEquipmentTypeVersion(equipmentTypeServiceV2);
            _EquipmentTypeVersions.Add(equipmentTypeServiceV2, equipmentTypeVersion);
        }
        result = new Tuple<string, string, string, EquipmentTypeVersion>(equipmentTypeServiceV2, componentsCellComponentCellComponent.Equipment.EquipmentType.Name, componentsCellComponentCellComponent.Equipment.EquipmentType.Version, equipmentTypeVersion);
        return result;
    }

    protected Tuple<string, string> GetParameterizedModelObjectDefinitionTypeTuple(Tuple<string, string, string, EquipmentTypeVersion> equipmentTypeVersionTuple)
    {
        Tuple<string, string> result;
        string parameterizedModelObjectDefinitionType;
        if (_FileConnectorConfigurations.ContainsKey(equipmentTypeVersionTuple.Item1))
            parameterizedModelObjectDefinitionType = _ParameterizedModelObjectDefinitionTypes[equipmentTypeVersionTuple.Item1];
        else
            parameterizedModelObjectDefinitionType = equipmentTypeVersionTuple.Item4.FileHandlerObjectTypes.ParameterizedModelObjectDefinition.Type;
        result = new Tuple<string, string>(equipmentTypeVersionTuple.Item1, parameterizedModelObjectDefinitionType);
        return result;
    }

    protected IList<ModelObjectParameterDefinition> GetModelObjectParameters(string json)
    {
        IList<ModelObjectParameterDefinition> results;
        JsonSerializerOptions jsonSerializerOptions = new()
        { Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) } };
        JsonElement jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
        string parameters = "Parameters";
        string fileHandlerObjectTypes = nameof(FileHandlerObjectTypes);
        string parameterizedModelObjectDefinition = nameof(ParameterizedModelObjectDefinition);
        if (!json.Contains(fileHandlerObjectTypes) || !json.Contains(parameterizedModelObjectDefinition))
            throw new Exception();
        jsonElement = jsonElement.GetProperty(fileHandlerObjectTypes);
        if (jsonElement.ValueKind != JsonValueKind.Object)
            throw new Exception();
        jsonElement = jsonElement.GetProperty(parameterizedModelObjectDefinition);
        if (jsonElement.ValueKind != JsonValueKind.Object)
            throw new Exception();
        jsonElement = jsonElement.GetProperty(parameters);
        if (jsonElement.ValueKind != JsonValueKind.Array)
            throw new Exception();
        results = JsonSerializer.Deserialize<IList<ModelObjectParameterDefinition>>(jsonElement.ToString(), jsonSerializerOptions);
        return results;
    }

    protected Tuple<string, IList<ModelObjectParameterDefinition>> GetModelObjectParameters(Tuple<string, string, string, EquipmentTypeVersion> equipmentTypeVersionTuple)
    {
        Tuple<string, IList<ModelObjectParameterDefinition>> result;
        IList<ModelObjectParameterDefinition> modelObjectParameters;
        if (_FileConnectorConfigurations.ContainsKey(equipmentTypeVersionTuple.Item1))
            modelObjectParameters = _ModelObjectParameters[equipmentTypeVersionTuple.Item1];
        else
        {
            string json = JsonSerializer.Serialize(equipmentTypeVersionTuple.Item4, new JsonSerializerOptions { WriteIndented = true });
            modelObjectParameters = GetModelObjectParameters(json);
        }
        result = new Tuple<string, IList<ModelObjectParameterDefinition>>(equipmentTypeVersionTuple.Item1, modelObjectParameters);
        return result;
    }

    protected string[] GetEquipmentDictionaryStrings(ComponentsCellComponentCellComponentEquipment componentsCellComponentCellComponentEquipment, EquipmentTypeVersion equipmentTypeVersion)
    {
        string[] results;
        string equipmentDictionaryName;
        string equipmentDictionaryVersionName;
        if (_SkipEquipmentDictionary || equipmentTypeVersion?.EventActionSequences is null || !equipmentTypeVersion.EventActionSequences.Any() || !(from l in equipmentTypeVersion.EventActionSequences where l.HandledEvent.StartsWith("Equipment.FileRead") select 1).Any())
        {
            equipmentDictionaryName = string.Empty;
            equipmentDictionaryVersionName = string.Empty;
        }
        else
        {
            if (componentsCellComponentCellComponentEquipment?.EquipmentDictionaries.CellEquipmentDictionaryReference is null)
            {
                // equipmentDictionaryName = equipmentTypeVersion.Dictionaries.EquipmentTypeDictionaryReference.DictionaryName;
                // equipmentDictionaryVersionName = equipmentTypeVersion.Dictionaries.EquipmentTypeDictionaryReference.DictionaryVersion;
                equipmentDictionaryName = string.Empty;
                equipmentDictionaryVersionName = string.Empty;
            }
            else
            {
                equipmentDictionaryName = componentsCellComponentCellComponentEquipment.EquipmentDictionaries.CellEquipmentDictionaryReference.DictionaryName;
                equipmentDictionaryVersionName = componentsCellComponentCellComponentEquipment.EquipmentDictionaries.CellEquipmentDictionaryReference.DictionaryVersion;
            }
        }
        results = new string[] { equipmentDictionaryName, equipmentDictionaryVersionName };
        return results;
    }

    protected static EquipmentDictionaryVersion GetEquipmentDictionaryVersion(string url)
    {
        EquipmentDictionaryVersion result;
        string xml;
        try
        {
            xml = XDocument.Load(url).ToString();
        }
        catch (System.Exception exception)
        {
            throw new Exception(string.Concat(url, System.Environment.NewLine, exception.Message));
        }
        ConfigurationData configurationData = ParseXML<ConfigurationData>(xml, throwExceptions: true);
        byte[] byteArray = Convert.FromBase64String(configurationData.Data);
        string decodedCellInstanceConfigurationData = Encoding.Unicode.GetString(byteArray);
        if (xml.Length <= 41)
            throw new Exception(string.Concat("xml isn't valid {", xml, "}"));
        decodedCellInstanceConfigurationData = decodedCellInstanceConfigurationData.Substring(41).Replace("i:type", "i___type");
        result = ParseXML<EquipmentDictionaryVersion>(decodedCellInstanceConfigurationData, throwExceptions: true);
        return result;
    }

    protected Tuple<string, string, string, EquipmentDictionaryVersion> GetEquipmentDictionaryVersionTuple(CellInstanceVersion cellInstanceVersion, string cellInstanceConnectionName, EquipmentTypeVersion equipmentTypeVersion)
    {
        Tuple<string, string, string, EquipmentDictionaryVersion> result;
        string equipmentDictionaryName;
        string equipmentDictionaryVersionName;
        EquipmentDictionaryVersion equipmentDictionaryVersion;
        Dictionary<string, int[]> componentModelComponentsIndexes = GetComponentModelComponentsIndexes(cellInstanceVersion, cellInstanceConnectionName);
        int[] cellInstanceConnectionNameIndexes = GetCellInstanceConnectionNameIndexes(cellInstanceConnectionName, componentModelComponentsIndexes);
        ComponentsCellComponentCellComponent componentsCellComponentCellComponent = cellInstanceVersion.ComponentModel.Components[cellInstanceConnectionNameIndexes[0]].Children[cellInstanceConnectionNameIndexes[1]];
        string[] segments = GetEquipmentDictionaryStrings(componentsCellComponentCellComponent.Equipment, equipmentTypeVersion);
        if (_SkipEquipmentDictionary || segments is null || segments.Length != 2 || string.IsNullOrEmpty(segments[0]) || string.IsNullOrEmpty(segments[1]))
        {
            equipmentDictionaryName = string.Empty;
            equipmentDictionaryVersionName = string.Empty;
        }
        else
        {
            equipmentDictionaryName = segments[0];
            equipmentDictionaryVersionName = segments[1];
        }
        string equipmentDictionaryServiceV2 = string.Concat("http://", _HostNameAndPort, "/EquipmentDictionaryServiceV2/", equipmentDictionaryName, "/", equipmentDictionaryVersionName, "/configuration");
        if (string.IsNullOrEmpty(equipmentDictionaryName) || string.IsNullOrEmpty(equipmentDictionaryVersionName))
            equipmentDictionaryVersion = null;
        else
        {
            if (_EquipmentDictionaryVersions.ContainsKey(equipmentDictionaryServiceV2))
                equipmentDictionaryVersion = _EquipmentDictionaryVersions[equipmentDictionaryServiceV2];
            else
            {
                equipmentDictionaryVersion = GetEquipmentDictionaryVersion(equipmentDictionaryServiceV2);
                _EquipmentDictionaryVersions.Add(equipmentDictionaryServiceV2, equipmentDictionaryVersion);
            }
        }
        result = new Tuple<string, string, string, EquipmentDictionaryVersion>(equipmentDictionaryServiceV2, equipmentDictionaryName, equipmentDictionaryVersionName, equipmentDictionaryVersion);
        return result;
    }

    protected Tuple<string, List<Tuple<string, string>>> GetEquipmentDictionaryIsAlwaysEnabledEventsTuple(Tuple<string, string, string, EquipmentDictionaryVersion> equipmentDictionaryVersionTuple)
    {
        Tuple<string, List<Tuple<string, string>>> result;
        List<Tuple<string, string>> results;
        if (_SkipEquipmentDictionary)
            results = new List<Tuple<string, string>>();
        else if (string.IsNullOrEmpty(equipmentDictionaryVersionTuple.Item1))
            throw new Exception();
        else if (equipmentDictionaryVersionTuple?.Item4?.Events?.Event is null)
            results = new List<Tuple<string, string>>();
        else if (_EquipmentDictionaryEventDescriptions.ContainsKey(equipmentDictionaryVersionTuple.Item1))
            results = _EquipmentDictionaryEventDescriptions[equipmentDictionaryVersionTuple.Item1];
        else
        {
            results = new List<Tuple<string, string>>();
            foreach (EquipmentDictionaryVersionEventsEvent equipmentDictionaryVersionEventsEvent in equipmentDictionaryVersionTuple.Item4.Events.Event)
            {
                if (string.IsNullOrEmpty(equipmentDictionaryVersionEventsEvent.Description))
                    continue;
                if (!equipmentDictionaryVersionEventsEvent.IsAlwaysEnabled)
                    continue;
                results.Add(new Tuple<string, string>(equipmentDictionaryVersionEventsEvent.Name, equipmentDictionaryVersionEventsEvent.Description));
            }
        }
        result = new Tuple<string, List<Tuple<string, string>>>(equipmentDictionaryVersionTuple.Item1, results);
        return result;
    }

    protected Dictionary<string, object> GetKeyValuePairs(string cellInstanceName, string cellInstanceVersionName, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, List<Tuple<string, string>> equipmentDictionaryIsAlwaysEnabledEvents)
    {
        Dictionary<string, object> results = new()
        {
            { nameof(Environment), _Environment },
            { nameof(HostNameAndPort), _HostNameAndPort },
            { nameof(cellInstanceName), cellInstanceName },
            { nameof(equipmentTypeName), equipmentTypeName },
            { nameof(cellInstanceVersionName), cellInstanceVersionName },
            { nameof(equipmentDictionaryName), equipmentDictionaryName },
            { nameof(cellInstanceConnectionName), cellInstanceConnectionName },
            { nameof(FileConnectorConfiguration), fileConnectorConfiguration },
            { nameof(IList<ModelObjectParameterDefinition>), modelObjectParameters },
            { nameof(parameterizedModelObjectDefinitionType), parameterizedModelObjectDefinitionType },
            { nameof(equipmentDictionaryIsAlwaysEnabledEvents), equipmentDictionaryIsAlwaysEnabledEvents }
        };
        return results;
    }

    public string[] GetCSharpText(string testName)
    {
        string[] results;
        string[] segments = GetSegments(testName);
        FileInfo fileInfo = GetFileName(segments);
        string cellInstanceName = GetCellInstanceName(segments);
        string cellInstanceVersionName = GetCellInstanceVersionName(segments);
        string cellInstanceConnectionName = GetCellInstanceConnectionName(segments);
        if (!string.IsNullOrEmpty(cellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName))
            _ = Directory.CreateDirectory(fileInfo.Directory.FullName);
        Tuple<string, CellInstanceVersion> cellInstanceVersionTuple = GetCellInstanceVersionTuple(cellInstanceName, cellInstanceVersionName);
        results = GetCSharpTextB(fileInfo, cellInstanceName, cellInstanceVersionName, cellInstanceVersionTuple.Item2);
        return results;
    }

    public string[] GetConfiguration(MethodBase methodBase)
    {
        string[] results;
        string[] segments = GetSegments(methodBase.Name);
        FileInfo fileInfo = GetFileName(segments);
        string cellInstanceName = GetCellInstanceName(segments);
        string cellInstanceVersionName = GetCellInstanceVersionName(segments);
        string cellInstanceConnectionName = GetCellInstanceConnectionName(segments);
        if (!string.IsNullOrEmpty(cellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName))
            _ = Directory.CreateDirectory(fileInfo.Directory.FullName);
        Tuple<string, CellInstanceVersion> cellInstanceVersionTuple = GetCellInstanceVersionTuple(cellInstanceName, cellInstanceVersionName);
        Tuple<string, FileConnectorConfiguration> fileConnectorConfigurationTuple = GetFileConnectorConfigurationTuple(cellInstanceVersionTuple, cellInstanceConnectionName);
        Tuple<string, string, string, EquipmentTypeVersion> equipmentTypeVersionTuple = GetEquipmentTypeVersionTuple(cellInstanceVersionTuple.Item2, cellInstanceConnectionName);
        Tuple<string, string> parameterizedModelObjectDefinitionTypeTuple = GetParameterizedModelObjectDefinitionTypeTuple(equipmentTypeVersionTuple);
        Tuple<string, IList<ModelObjectParameterDefinition>> modelObjectParametersTuple = GetModelObjectParameters(equipmentTypeVersionTuple);
        Tuple<string, string, string, EquipmentDictionaryVersion> equipmentDictionaryVersionTuple = GetEquipmentDictionaryVersionTuple(cellInstanceVersionTuple.Item2, cellInstanceConnectionName, equipmentTypeVersionTuple.Item4);
        Tuple<string, List<Tuple<string, string>>> equipmentDictionaryIsAlwaysEnabledEventsTuple = GetEquipmentDictionaryIsAlwaysEnabledEventsTuple(equipmentDictionaryVersionTuple);
        Dictionary<string, object> objects = GetKeyValuePairs(cellInstanceName, cellInstanceVersionName, cellInstanceConnectionName, fileConnectorConfigurationTuple.Item2, equipmentTypeVersionTuple.Item2, parameterizedModelObjectDefinitionTypeTuple.Item2, modelObjectParametersTuple.Item2, equipmentDictionaryVersionTuple.Item2, equipmentDictionaryIsAlwaysEnabledEventsTuple.Item2);
        string json = JsonSerializer.Serialize(objects, new JsonSerializerOptions { WriteIndented = true });
        results = new string[] { fileInfo.FullName, json };
        return results;
    }

    public IFileRead Get(MethodBase methodBase, string sourceFileLocation, string sourceFileFilter, bool useCyclicalForDescription)
    {
        IFileRead result;
        string[] segments = GetSegments(methodBase.Name);
        FileInfo fileInfo = GetFileName(segments);
        string cellInstanceName = GetCellInstanceName(segments);
        string cellInstanceVersionName = GetCellInstanceVersionName(segments);
        Dictionary<string, string> fileParameter = new();
        string cellInstanceConnectionName = GetCellInstanceConnectionName(segments);
        if (!string.IsNullOrEmpty(cellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName))
            _ = Directory.CreateDirectory(fileInfo.Directory.FullName);
        Dictionary<string, List<long>> dummyRuns = new();
        Tuple<string, CellInstanceVersion> cellInstanceVersionTuple = GetCellInstanceVersionTuple(cellInstanceName, cellInstanceVersionName);
        Tuple<string, FileConnectorConfiguration> fileConnectorConfigurationTuple = GetFileConnectorConfigurationTuple(cellInstanceVersionTuple, cellInstanceConnectionName);
        Tuple<string, string, string, EquipmentTypeVersion> equipmentTypeVersionTuple = GetEquipmentTypeVersionTuple(cellInstanceVersionTuple.Item2, cellInstanceConnectionName);
        Tuple<string, string> parameterizedModelObjectDefinitionTypeTuple = GetParameterizedModelObjectDefinitionTypeTuple(equipmentTypeVersionTuple);
        Tuple<string, IList<ModelObjectParameterDefinition>> modelObjectParametersTuple = GetModelObjectParameters(equipmentTypeVersionTuple);
        Tuple<string, string, string, EquipmentDictionaryVersion> equipmentDictionaryVersionTuple = GetEquipmentDictionaryVersionTuple(cellInstanceVersionTuple.Item2, cellInstanceConnectionName, equipmentTypeVersionTuple.Item4);

        _ = GetEquipmentDictionaryIsAlwaysEnabledEventsTuple(equipmentDictionaryVersionTuple);
        if (!string.IsNullOrEmpty(sourceFileLocation) && sourceFileLocation != fileConnectorConfigurationTuple.Item2.SourceFileLocation)
            fileConnectorConfigurationTuple.Item2.SourceFileLocation = sourceFileLocation;
        if (!string.IsNullOrEmpty(sourceFileFilter) && sourceFileFilter != fileConnectorConfigurationTuple.Item2.SourceFileFilter)
        {
            fileConnectorConfigurationTuple.Item2.SourceFileFilter = sourceFileFilter;
            fileConnectorConfigurationTuple.Item2.SourceFileFilters = sourceFileFilter.Split('|').ToList();
        }
        result = Adaptation.FileHandlers.CellInstanceConnectionName.Get(this, fileParameter, cellInstanceName, cellInstanceConnectionName, fileConnectorConfigurationTuple.Item2, equipmentTypeVersionTuple.Item2, parameterizedModelObjectDefinitionTypeTuple.Item2, modelObjectParametersTuple.Item2, equipmentDictionaryVersionTuple.Item2, dummyRuns, useCyclicalForDescription, isEAFHosted: false);
        return result;
    }

    public string[] GetVariables(MethodBase methodBase, string check)
    {
        string[] results;
        string[] lines;
        string ipdsfFile;
        string textFileDirectory;
        string fileNameWithoutExtension;
        string searchPattern = "*.ipdsf";
        string sourceFileFilter = string.Empty;
        string sourceFileLocation = string.Empty;
        string[] segments = GetSegments(methodBase);
        string ticks = GetTicks(segments);
        FileInfo fileInfo = GetFileName(segments);
        string[] textFiles = GetTextFiles(segments);
        string cellInstanceName = GetCellInstanceName(segments);
        string rawCellInstanceName = GetRawCellInstanceName(segments);
        string cellInstanceConnectionName = GetCellInstanceConnectionName(segments);
        string cellInstanceConnectionNameFromMethodBaseName = GetCellInstanceConnectionNameFromMethodBaseName(segments);
        string methodBaseNameWithActualCICN = GetMethodBaseNameWithActualCICN(methodBase.Name, rawCellInstanceName, cellInstanceConnectionNameFromMethodBaseName, cellInstanceConnectionName, ticks);
        if (!textFiles.Any())
            textFileDirectory = string.Empty;
        else
            textFileDirectory = Path.GetDirectoryName(textFiles[0]);
        foreach (string textFile in textFiles)
        {
            lines = File.ReadAllLines(textFile);
            if (lines.Length != 1)
                continue;
            fileNameWithoutExtension = Path.GetFileNameWithoutExtension(textFile);
            if (fileNameWithoutExtension == nameof(FileConnectorConfiguration.SourceFileFilter))
                sourceFileFilter = lines[0];
            else if (fileNameWithoutExtension == nameof(FileConnectorConfiguration.SourceFileLocation))
            {
                segments = lines[0].Split(new string[] { ticks }, StringSplitOptions.None);
                if (segments.Length > 2)
                    throw new Exception("Ticks should only appear once in source file location!");
                if (segments.Length != 2)
                    throw new Exception("Ticks missing from source file location!");
                if (!segments[1].EndsWith(methodBaseNameWithActualCICN.Replace(ticks, string.Empty)))
                    throw new Exception("Method name missing from source file location!");
                sourceFileLocation = lines[0];
            }
        }
        if (!Directory.Exists(fileInfo.Directory.FullName))
            _ = Directory.CreateDirectory(fileInfo.Directory.FullName);
        if (!fileInfo.Exists)
            throw new Exception();
        string json = File.ReadAllText(fileInfo.FullName);
        if (!json.Contains(check))
            throw new Exception();
        if (!json.Contains(nameof(FileConnectorConfiguration)))
            throw new Exception();
        JsonElement jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
        JsonElement fileConnectorConfigurationJsonElement = jsonElement.GetProperty(nameof(FileConnectorConfiguration));
        if (fileConnectorConfigurationJsonElement.ValueKind != JsonValueKind.Object)
            throw new Exception();
        JsonSerializerOptions jsonSerializerOptions = new()
        { Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) } };
        FileConnectorConfiguration fileConnectorConfiguration = JsonSerializer.Deserialize<FileConnectorConfiguration>(fileConnectorConfigurationJsonElement.ToString(), jsonSerializerOptions);
        if (!string.IsNullOrEmpty(sourceFileFilter))
            fileConnectorConfiguration.SourceFileFilter = sourceFileFilter;
        if (!string.IsNullOrEmpty(sourceFileLocation))
            fileConnectorConfiguration.SourceFileLocation = sourceFileLocation;
        if (string.IsNullOrEmpty(sourceFileLocation))
            ipdsfFile = searchPattern;
        else
        {
            string ipdsfDirectory = Path.Combine(sourceFileLocation, "ipdsf");
            if (!Directory.Exists(ipdsfDirectory))
                ipdsfFile = searchPattern;
            else
            {
                string[] files = Directory.GetFiles(ipdsfDirectory, searchPattern, SearchOption.TopDirectoryOnly);
                if (files.Any())
                    ipdsfFile = files[0];
                else
                    ipdsfFile = searchPattern;
            }
        }
        if (ipdsfFile == searchPattern)
            throw new Exception();
        results = new string[] { fileInfo.FullName, json, fileConnectorConfiguration.SourceFileLocation, fileConnectorConfiguration.SourceFileFilter, ipdsfFile, textFileDirectory };
        if (string.IsNullOrEmpty(results[0]))
            throw new Exception();
        if (string.IsNullOrEmpty(results[1]))
            throw new Exception();
        if (string.IsNullOrEmpty(results[2]))
            throw new Exception();
        if (string.IsNullOrEmpty(results[3]))
            throw new Exception();
        if (string.IsNullOrEmpty(results[4]))
            throw new Exception();
        if (string.IsNullOrEmpty(results[5]))
            throw new Exception();
        return results;
    }

}
// namespace _Tests.Helpers { public class AdaptationTesting { } }
// 2022-02-02 -> AdaptationTesting