using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;

using Newtonsoft.Json;

using FasdCockpitBase.Models;
using FasdCockpitCommunicationDemo;
using C4IT.FASD.Base;
using static C4IT.Logging.cLogManager;
using FasdCockpitBase;
using C4IT.Logging;


namespace C4IT.FASD.Cockpit.Communication
{
    public class cFasdCockpitCommunicationDemo : cFasdCockpitCommunicationBase
    {
        private int ticketCounter = 475;

        private readonly List<cF4SDHealthCardJsonRawData> MockupData = new List<cF4SDHealthCardJsonRawData>();

        private readonly Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable> MockupPickup = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>();

        private readonly Dictionary<string, string> CategoryNameLookup = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

        #region Ticketübersicht

        private readonly Dictionary<string, Dictionary<string, List<DemoTicketRecord>>> TicketOverviewRelations =
            new Dictionary<string, Dictionary<string, List<DemoTicketRecord>>>(StringComparer.OrdinalIgnoreCase);
        private readonly HashSet<string> _loadedOverviewPlacements = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
        private readonly object _demoTicketSync = new object();

        #endregion
        public cFasdCockpitCommunicationDemo()
        {
            if (LoadMockupData(out var loadedData))
                MockupData = loadedData;

            MockupPickup = LoadMockupPickup();
            BuildCategoryLookup();
            LoadGeneratedTickets();
        }

        public override bool IsDemo() => true;

        private Dictionary<Guid, cFasdApiSearchResultCollection> SearchCache = new Dictionary<Guid, cFasdApiSearchResultCollection>();

        private Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable> LoadMockupPickup()
        {
            var CM = MethodBase.GetCurrentMethod();
            LogMethodBegin(CM);
            try
            {
                var pickupData = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>();

                string executingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                string path = Path.Combine(executingDirectory, "MockupPickup");

                var sampleDataFiles = Directory.GetFiles(path);

                foreach (var file in sampleDataFiles)
                {
                    try
                    {
                        string jsonText;
                        using (StreamReader streamReader = new StreamReader(file))
                        {
                            jsonText = streamReader.ReadToEnd();
                        }

                        var newRawData = JsonConvert.DeserializeObject<cF4SDHealthCardRawData.cHealthCardTable>(jsonText);

                        pickupData[newRawData.Name] = newRawData;
                    }
                    catch (Exception E)
                    {
                        LogException(E);
                    }
                }

                return pickupData;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                LogMethodEnd(CM);
            }

            return null;
        }

        private void BuildCategoryLookup()
        {
            CategoryNameLookup.Clear();

            if (MockupPickup == null || !MockupPickup.TryGetValue("M42Wpm-Ticket-Categories", out var table))
                return;

            if (table?.Columns == null)
                return;

            if (!table.Columns.TryGetValue("id", out var idColumn))
                return;

            if (!table.Columns.TryGetValue("Name", out var nameColumn))
                return;

            for (int i = 0; i < idColumn.Values.Count; i++)
            {
                var id = idColumn.Values[i]?.ToString();
                if (string.IsNullOrWhiteSpace(id))
                    continue;

                var name = i < nameColumn.Values.Count ? nameColumn.Values[i]?.ToString() : null;
                if (string.IsNullOrWhiteSpace(name))
                    continue;

                CategoryNameLookup[id] = name;
            }
        }

        private string ResolveCategoryDisplayName(string categoryIdOrName)
        {
            if (string.IsNullOrWhiteSpace(categoryIdOrName))
                return categoryIdOrName;

            if (!Guid.TryParse(categoryIdOrName, out _))
                return categoryIdOrName;

            if (CategoryNameLookup.TryGetValue(categoryIdOrName, out var name))
                return name;

            return categoryIdOrName;
        }

        #region Ticketübersicht

        private void LoadGeneratedTickets()
        {
            try
            {
                TicketOverviewRelations.Clear();
                _loadedOverviewPlacements.Clear();

                var records = TicketOverviewDataStore.LoadTickets();
                foreach (var record in records)
                {
                    AppendDemoTicket(record);
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        public void RegisterGeneratedTicket(DemoTicketRecord record)
        {
            try
            {
                AppendDemoTicket(record);
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private void AppendDemoTicket(DemoTicketRecord record)
        {
            if (record == null)
                return;

            lock (_demoTicketSync)
            {
                if (record.TicketId == Guid.Empty || string.IsNullOrWhiteSpace(record.TileKey))
                    return;

                var tileKey = record.TileKey.Trim();
                var scopeKey = record.UseRoleScope ? "Role" : "Personal";
                var placementKey = $"{record.TicketId:N}|{tileKey}|{scopeKey}";
                if (!_loadedOverviewPlacements.Add(placementKey))
                    return;

                if (!TicketOverviewRelations.TryGetValue(tileKey, out var scopeDictionary))
                {
                    scopeDictionary = new Dictionary<string, List<DemoTicketRecord>>(StringComparer.OrdinalIgnoreCase);
                    TicketOverviewRelations[tileKey] = scopeDictionary;
                }

                if (!scopeDictionary.TryGetValue(scopeKey, out var definitions))
                {
                    definitions = new List<DemoTicketRecord>();
                    scopeDictionary[scopeKey] = definitions;
                }

                definitions.Add(record);

                var targetSample = MockupData.FirstOrDefault(data => data.SampleDataId == record.UserId);
                if (targetSample == null)
                    return;

                if (targetSample.Tickets.Any(ticket => ticket.Id == record.TicketId))
                    return;

                var generatedTicket = ConvertToTicket(record);
                targetSample.Tickets.Add(generatedTicket);
            }
        }

        private static cF4SDTicket ConvertToTicket(DemoTicketRecord record)
        {
            var status = enumTicketStatus.New;
            if (!string.IsNullOrWhiteSpace(record.StatusId) && Enum.TryParse(record.StatusId, true, out enumTicketStatus parsedStatus))
                status = parsedStatus;

            var detail = record.Detail ?? new DemoTicketDetail();
            var createdAt = record.CreatedAt == default ? DateTime.UtcNow : record.CreatedAt;

            var ticket = new cF4SDTicket
            {
                Id = record.TicketId,
                Name = record.DisplayName,
                Summary = record.Summary,
                Status = status,
                AffectedUser = detail.AffectedUser ?? record.UserDisplayName,
                Asset = detail.Asset,
                Category = detail.Category,
                ActivityType = record.ActivityType,
                Description = detail.Description,
                DescriptionHtml = detail.DescriptionHtml,
                Solution = detail.Solution,
                SolutionHtml = detail.SolutionHtml,
                CreationDate = createdAt.ToLocalTime(),
                CreationDaysSinceNow = Math.Max(0, (int)(DateTime.UtcNow - createdAt).TotalDays),
                Priority = detail.Priority ?? 0,
                CreationSource = cF4SDTicket.enumTicketCreationSource.F4SD,
                DirectLinks = new Dictionary<string, string>(),
                JournalItems = new List<cF4SDTicket.cTicketJournalItem>()
            };

            if (detail.Journal != null)
            {
                foreach (var entry in detail.Journal)
                {
                    var journalCreation = entry?.CreationDate ?? createdAt;
                    ticket.JournalItems.Add(new cF4SDTicket.cTicketJournalItem
                    {
                        Header = entry.Header,
                        Description = entry.Description,
                        DescriptionHtml = entry.DescriptionHtml,
                        IsVisibleForUser = entry.IsVisibleForUser,
                        CreationDate = journalCreation.ToLocalTime(),
                        CreationDaysSinceNow = Math.Max(0, (int)(DateTime.UtcNow - journalCreation).TotalDays)
                    });
                }
            }

            return ticket;
        }

        public override Task<Dictionary<string, int>> GetTicketOverviewCounts(IEnumerable<string> keys, bool useRoleScope)
        {
            var scopeKey = useRoleScope ? "Role" : "Personal";
            var comparer = StringComparer.OrdinalIgnoreCase;
            var result = new Dictionary<string, int>(comparer);

            var requestedKeys = keys == null
                ? TicketOverviewRelations.Keys.ToList()
                : keys.Where(k => !string.IsNullOrWhiteSpace(k)).Distinct(comparer).ToList();

            if (requestedKeys.Count == 0)
                requestedKeys.AddRange(TicketOverviewRelations.Keys);

            foreach (var key in requestedKeys)
            {
                if (string.IsNullOrWhiteSpace(key))
                    continue;

                if (TicketOverviewRelations.TryGetValue(key, out var scopeDictionary) &&
                    scopeDictionary != null &&
                    scopeDictionary.TryGetValue(scopeKey, out var definitions) &&
                    definitions != null)
                {
                    result[key] = definitions.Count;
                }
                else
                {
                    result[key] = 0;
                }
            }

            return Task.FromResult(result);
        }

        public override async Task<List<cF4sdApiSearchResultRelation>> GetTicketOverviewRelations(string key, bool useRoleScope, int count)
        {
            var CM = MethodBase.GetCurrentMethod();
            LogMethodBegin(CM);
            try
            {
                if (string.IsNullOrWhiteSpace(key))
                {
                    await SimulateTicketOverviewLatencyAsync(count);
                    return new List<cF4sdApiSearchResultRelation>();
                }
                var scopeKey = useRoleScope ? "Role" : "Personal";
                if (!TicketOverviewRelations.TryGetValue(key, out var scopeData) || scopeData == null)
                {
                    await SimulateTicketOverviewLatencyAsync(count);
                    return new List<cF4sdApiSearchResultRelation>();
                }
                if (!scopeData.TryGetValue(scopeKey, out var definitions) || definitions == null || definitions.Count == 0)
                {
                    await SimulateTicketOverviewLatencyAsync(count);
                    return new List<cF4sdApiSearchResultRelation>();
                }
                int requestedCount = count <= 0 ? definitions.Count : Math.Min(count, definitions.Count);
                await SimulateTicketOverviewLatencyAsync(requestedCount);
                var relations = new List<cF4sdApiSearchResultRelation>(requestedCount);
                foreach (var definition in definitions.Take(requestedCount))
                {
                    var detailTicket = FindTicketForOverviewRelation(definition);
                    var summary = definition.Summary ?? string.Empty;
                    if (detailTicket != null && !string.IsNullOrWhiteSpace(detailTicket.Summary))
                        summary = detailTicket.Summary;
                    var activityType = string.IsNullOrWhiteSpace(definition.ActivityType)
                        ? null
                        : definition.ActivityType.Trim();

                    var relation = new cF4sdApiSearchResultRelation
                    {
                        Type = enumF4sdSearchResultClass.Ticket,
                        DisplayName = definition.DisplayName ?? string.Empty,
                        Name = definition.DisplayName ?? string.Empty,
                        id = definition.TicketId,
                        Status = enumF4sdSearchResultStatus.Active,
                        Infos = new Dictionary<string, string>
                        {
                            ["Summary"] = summary,
                            ["StatusId"] = definition.StatusId ?? string.Empty,
                            ["UserDisplayName"] = definition.UserDisplayName ?? string.Empty,
                            ["UserAccount"] = definition.UserAccount ?? string.Empty,
                            ["UserDomain"] = definition.UserDomain ?? string.Empty,
                            ["ActivityType"] = activityType
                        },
                        Identities = new cF4sdIdentityList
                        {
                            new cF4sdIdentityEntry { Class = enumFasdInformationClass.Ticket, Id = definition.TicketId },
                            new cF4sdIdentityEntry { Class = enumFasdInformationClass.User, Id = definition.UserId }
                        }
                    };
                    relations.Add(relation);
                }
                return relations;
            }
            catch (Exception E)
            {
                LogException(E);
                return new List<cF4sdApiSearchResultRelation>();
            }
            finally
            {
                LogMethodEnd(CM);
            }
        }

        private cF4SDTicket FindTicketForOverviewRelation(DemoTicketRecord definition)
        {
            if (definition == null || definition.TicketId == Guid.Empty)
                return null;

            if (definition.UserId == Guid.Empty)
                return null;

            var selectedData = MockupData.FirstOrDefault(data => data.SampleDataId == definition.UserId);
            if (selectedData?.Tickets == null)
                return null;

            return selectedData.Tickets.FirstOrDefault(ticket => ticket.Id == definition.TicketId);
        }

        private static Task SimulateTicketOverviewLatencyAsync(int count)
        {
            int baseMs = 420;
            int perItem = 100;
            int capped = Math.Max(0, Math.Min(count, 5));
            int delay = Math.Max(240, Math.Min(baseMs + capped * perItem, 2000));
            return Task.Delay(delay);
        }

        #endregion

        private bool LoadMockupData(out List<cF4SDHealthCardJsonRawData> sampleData)
        {
            var CM = MethodBase.GetCurrentMethod();
            LogMethodBegin(CM);

            sampleData = new List<cF4SDHealthCardJsonRawData>();

            try
            {
                string executingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                string path = executingDirectory + @"\MockupData";

                var sampleDataFiles = Directory.GetFiles(path);

                foreach (var file in sampleDataFiles)
                {
                    try
                    {
                        using (var streamReader = new StreamReader(file))
                        {
                            string jsonText = streamReader.ReadToEnd();
                            var newRawData = JsonConvert.DeserializeObject<cF4SDHealthCardJsonRawData>(jsonText);

                            if (newRawData == null || string.IsNullOrWhiteSpace(newRawData.SampleDataName))
                            {
                                LogEntry($"Skip mockup data '{Path.GetFileName(file)}' because SampleDataName is missing.", LogLevels.Warning);
                                continue;
                            }

                            sampleData.Add(newRawData);
                        }
                    }
                    catch (Exception E)
                    {
                        LogException(E);
                    }
                }

                return true;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                LogMethodEnd(CM);
            }

            return false;
        }

        public override bool CheckConnectionInfo() => true;

        public override async Task<cCheckConnectionResult> CheckConnection(Version minServerVersion)
        {
            var CM = MethodBase.GetCurrentMethod();
            LogMethodBegin(CM);
            try
            {
                await Task.CompletedTask;
                var output = new cCheckConnectionResult() { ConnectionStatus = enumConnectionStatus.connected };
                output.ApiConnectionInfo = new cFasdApiConnectionInfo() { ServerVersion = "1.0.0.0", MinCockpitVersion = "0.0.0.0" };
                return output;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                LogMethodEnd(CM);
            }

            return null;
        }

        public override Task<Guid> GetUserIdByAccount(string userName, string userDomain) => Task.FromResult(Guid.NewGuid());

        public async override Task<cF4sdUserInfo> WinLogon()
        {
            await Task.CompletedTask;

            var _retVal = new cF4sdUserInfo()
            {
                Id = Guid.NewGuid(),
                Name = "Demo",
                LogonTime = DateTime.UtcNow,
                AccountType = cF4sdUserInfo.enumAccountType.AdUser,
                AdAccount = "demo",
                Roles = new List<string>() { "Cockpit.User", "Cockpit.Admin", "Cockpit.TicketAgent" }
            };

            return _retVal;
        }

        public override Task<cF4SdUserInfoChange> RegisterExternalTokenAsync(cF4SDTokenRegistration Token) => Task.FromResult<cF4SdUserInfoChange>(null);

        public override Task<cF4SDAdditionalUserInfo> GetAdditionalUserInfo(enumAdditionalAuthentication Type) => Task.FromResult<cF4SDAdditionalUserInfo>(null);

        public override Task<bool> IsAnalyticsModuleActive() => Task.FromResult(false);

        public override Task<bool> CreateUserSession(cF4SDUserSessionParameters sessionParameters) => Task.FromResult(true);

        public override Task CloseUserSession(Guid sessionId) => Task.CompletedTask;

        public override Task<bool> StartCase(cF4SDCaseParameters caseParameters) => Task.FromResult(true);

        public override Task<bool> UpdateCase(cF4SDCaseStatusParameters caseStatusParameters, List<cF4SDCaseTime> caseTimes) => Task.FromResult(true);

        public override Task<bool> ReportQuickAction(cF4SDQuickActionParameters quickActionParameters) => Task.FromResult(true);

        public override Task<bool> KeepAliveCase(Guid caseId) => Task.FromResult(true);

        public override Task<bool> KeepAliveSession(Guid sessionId) => Task.FromResult(true);

        public override Task<cFasdBaseConfig> GetConfiguration(enumFasdConfigurationType configType) => Task.FromResult(cFasdBaseConfig.GetConfigByType(configType, ReadOnly: true));

        //public override async Task<cFasdApiSearchResultCollection> GetSearchResultsDetailed(string searchValue, int charactersToTypeForSearch, CancellationToken cancellationToken)
        //{
        //    var CM = MethodBase.GetCurrentMethod();
        //    LogMethodBegin(CM);
        //    try
        //    {
        //        var output = new cFasdApiSearchResultCollection();
        //        //if (searchValue.ToCharArray().Length < charactersToTypeForSearch)
        //        //    return output;

        //        foreach (var data in MockupData)
        //        {
        //            if (data.SampleDataName.ToLowerInvariant().Contains(searchValue.ToLowerInvariant()))
        //            {
        //                //todo: add a field in demo data
        //                var searchResultClass = enumF4sdSearchResultClass.User;

        //                if (data.SampleDataId.ToString() == "2897b20b-9457-49f0-a078-6cb2ac241ab2")
        //                    searchResultClass = enumF4sdSearchResultClass.Computer;

        //                output[data.SampleDataName] = new List<cFasdApiSearchResultEntry>() { new cFasdApiSearchResultEntry() { id = data.SampleDataId, Name = data.SampleDataName, Type = searchResultClass } };
        //            }
        //        }

        //        return output;
        //    }
        //    catch (Exception E)
        //    {
        //        LogException(E);
        //    }
        //    finally
        //    {
        //        LogMethodEnd(CM);
        //    }

        //    await Task.CompletedTask;
        //    return null;
        //}

        public override async Task<Guid?> GetSearchResultsStart(string searchValue, CancellationToken cancellationToken)
        {
            await Task.CompletedTask;


            var CM = MethodBase.GetCurrentMethod();
            LogMethodBegin(CM);
            try
            {
                var output = new cFasdApiSearchResultCollection();
                //if (searchValue.ToCharArray().Length < charactersToTypeForSearch)
                //    return output;

                foreach (var data in MockupData)
                {
                    if (data.SampleDataName.ToLowerInvariant().Contains(searchValue.ToLowerInvariant()))
                    {
                        //todo: add a field in demo data
                        var searchResultClass = enumF4sdSearchResultClass.User;

                        if (data.SampleDataId.ToString() == "2897b20b-9457-49f0-a078-6cb2ac241ab2")
                            searchResultClass = enumF4sdSearchResultClass.Computer;

                        output[data.SampleDataName] = new List<cFasdApiSearchResultEntry>() { new cFasdApiSearchResultEntry() { id = data.SampleDataId, Name = data.SampleDataName, DisplayName = data.SampleDataName, Type = searchResultClass } };
                    }
                }

                var newID = Guid.NewGuid();
                SearchCache[newID] = output;
                return newID;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                LogMethodEnd(CM);
            }

            await Task.CompletedTask;
            return null;
        }

        public override async Task<cFasdApiSearchResultCollection> GetSearchResultsResult(Guid taskID, CancellationToken cancellationToken)
        {
            await Task.CompletedTask;

            if (SearchCache.TryGetValue(taskID, out var _result))
            {
                SearchCache.Remove(taskID);
                return _result;
            }
            return null;
        }

        public override Task GetSearchResultsStop(Guid taskID, CancellationToken cancellationToken) => Task.CompletedTask;

        public override async Task<cFasdApiSearchResultCollection> GetPhoneSearchResults(cPhoneSearchParameters searchInfo)
        {
            var output = new cFasdApiSearchResultCollection();
            try
            {
                foreach (var data in MockupData)
                {
                    if (data.SampleDataName.Equals(searchInfo.name, StringComparison.InvariantCultureIgnoreCase))
                    {
                        var searchResultClass = enumF4sdSearchResultClass.Phone;
                        output[data.SampleDataName] = new List<cFasdApiSearchResultEntry>() { new cFasdApiSearchResultEntry() { id = data.SampleDataId, Name = data.SampleDataName, DisplayName = data.SampleDataName, Type = searchResultClass } };
                    }
                }

                await Task.CompletedTask;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            return output;
        }

        public override async Task<cFasdApiSearchResultCollection> GetComputerSearchResults(string Name, string Domain)
        {
            var output = new cFasdApiSearchResultCollection();
            try
            {
                foreach (var data in MockupData)
                {
                    var computerName = data.Tables.FirstOrDefault(table => table.Name == "agnt-computer")?.Columns.FirstOrDefault(column => column.ColumnName == "Name")?.Values[0];

                    if (computerName != null && computerName.ToString().Equals(Name, StringComparison.InvariantCultureIgnoreCase))
                    {
                        var searchResultClass = enumF4sdSearchResultClass.Computer;
                        output[computerName.ToString()] = new List<cFasdApiSearchResultEntry>() { new cFasdApiSearchResultEntry() { id = computerName.ToString().Equals("C4-TT007") ? Guid.Parse("2CC166CF-F1F1-4473-A7CD-0471E088CA3C") : Guid.NewGuid(), Name = data.SampleDataName, DisplayName = computerName.ToString(), Type = searchResultClass } };
                    }
                }

                await Task.CompletedTask;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            return output;
        }

        public override async Task<cFasdApiSearchResultCollection> GetUserSearchResults(string Name, List<string> SIDs)
        {
            var output = new cFasdApiSearchResultCollection();
            try
            {
                foreach (var data in MockupData)
                {
                    if (!string.Equals(data.SampleDataName, Name, StringComparison.InvariantCultureIgnoreCase))
                        continue;

                    //todo: add a field in demo data
                    var searchResultClass = enumF4sdSearchResultClass.User;
                    if (!output.ContainsKey(data.SampleDataName))
                    {
                        output[data.SampleDataName] = new List<cFasdApiSearchResultEntry>()
                        {
                            new cFasdApiSearchResultEntry()
                            {
                                id = data.SampleDataId,
                                Name = data.SampleDataName,
                                DisplayName = data.SampleDataName,
                                Type = searchResultClass
                            }
                        };
                    }
                }

                await Task.CompletedTask;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            return output;
        }

        public override async Task<List<cF4sdApiSearchResultRelation>> GetSearchResultRelations(enumF4sdSearchResultClass resultType, List<cFasdApiSearchResultEntry> searchResults)
        {
            const string constGuidPeterAnwender = "436e8d67-1b9b-4b1a-83e9-0b1e8fa0173b";
            const string constGuidCarlos = "6180aa17-ba2d-455a-bf2f-ec4a075c2d64";
            const string constGuidCarlKriminell = "a642bf1e-1fc1-4ba1-8db1-a93531da80a5";
            const string constGuidFraukeNichtAnwender = "2183284f-ba95-4eb8-ac13-6c2f70857e98";
            const string constGuidTimoTicket = "42c760d6-90e8-469f-b2fe-ac7d4cc6cb0a";
            const string constGuidTimoTicketComputer = "2cc166cf-f1f1-4473-a7cd-0471e088ca3c";
            const string constGuidComputer = "2897b20b-9457-49f0-a078-6cb2ac241ab2";
            const string constGuidPaulPerschmann = "8c3ca0fb-f18c-4893-ad83-290e6e02f352";
            const string constGuidVeraVirtuell = "916db36b-fb6e-4212-81c1-e72acdab77d2";
            const string constGuidOlliOffline = "75b68176-4397-49c1-aaee-e023675bcd56";

            const string constGuidMischaMobile = "6a3d4e89-a7ad-4a48-95fa-8cde4dd50c80";


            var resultIds = searchResults.Select(resultData => resultData.id).ToList();

            var output = new List<cF4sdApiSearchResultRelation>();

            switch (resultIds.First().ToString())
            {
                case constGuidOlliOffline: // Olli Offline
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4-NB005", DisplayName = "C4-NB005", Infos = new Dictionary<string, string>() { ["UserAccountType"] = "AD", ["UserAccount"] = "C4-NB005", ["UserDomain"] = "C4IT" }, LastUsed = DateTime.UtcNow.AddDays(-10), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.Parse(constGuidOlliOffline) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });

                    output.Add(new cF4sdApiSearchResultRelation()
                    {
                        id = Guid.Parse(constGuidOlliOffline),
                        Name = "VM-W11MS02",
                        DisplayName = "VM-W11MS02",
                        LastUsed = DateTime.UtcNow.AddDays(-1),
                        Type = enumF4sdSearchResultClass.VirtualSession,
                        UsingLevel = 1,
                        Status = enumF4sdSearchResultStatus.Inactive,
                        Infos = new Dictionary<string, string>()
                        {
                            ["Status"] = enumF4sdSearchResultStatus.Inactive.ToString()
                        },
                        Identities = new cF4sdIdentityList()
                    {
                        new cF4sdIdentityEntry(){
                            Class = enumFasdInformationClass.User,
                            Id = Guid.Parse(constGuidOlliOffline)
                        },
                        new cF4sdIdentityEntry(){
                            Class = enumFasdInformationClass.VirtualSession,
                            Id = Guid.Parse(constGuidOlliOffline)
                        }
                    }
                    });
                    break;
                case constGuidVeraVirtuell: // Vera Virtuell
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4-NB005", DisplayName = "C4-NB005", Infos = new Dictionary<string, string>() { ["UserAccountType"] = "AD", ["UserAccount"] = "C4-NB005", ["UserDomain"] = "C4IT" }, LastUsed = DateTime.UtcNow.AddDays(-10), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.Parse(constGuidVeraVirtuell) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = Guid.NewGuid() } } });

                    output.Add(new cF4sdApiSearchResultRelation()
                    {
                        id = Guid.Parse(constGuidVeraVirtuell),
                        Name = "VM-W11MS03",
                        DisplayName = "VM-W11MS03",
                        LastUsed = DateTime.UtcNow,
                        Type = enumF4sdSearchResultClass.VirtualSession,
                        UsingLevel = 1,
                        Status = enumF4sdSearchResultStatus.Active,
                        Infos = new Dictionary<string, string>()
                        {
                            ["Status"] = enumF4sdSearchResultStatus.Active.ToString()
                        },
                        Identities = new cF4sdIdentityList()
                        {
                            new cF4sdIdentityEntry(){
                                Class = enumFasdInformationClass.VirtualSession,
                                Id = Guid.Parse(constGuidVeraVirtuell)
                            },
                            new cF4sdIdentityEntry(){
                                Class = enumFasdInformationClass.User,
                                Id = Guid.Parse(constGuidVeraVirtuell)
                        }
                    }
                    });

                    output.Add(new cF4sdApiSearchResultRelation()
                    {
                        id = Guid.Parse(constGuidVeraVirtuell),
                        Name = "VM-W11MS04",
                        DisplayName = "VM-W11MS04",
                        LastUsed = DateTime.UtcNow.AddDays(-2),
                        Type = enumF4sdSearchResultClass.VirtualSession,
                        UsingLevel = 0.2,
                        Status = enumF4sdSearchResultStatus.Inactive,
                        Infos = new Dictionary<string, string>()
                        {
                            ["Status"] = enumF4sdSearchResultStatus.Inactive.ToString()
                        },
                        Identities = new cF4sdIdentityList()
                        {
                            new cF4sdIdentityEntry(){
                                Class = enumFasdInformationClass.VirtualSession,
                                Id = Guid.Parse(constGuidVeraVirtuell)
                            },
                            new cF4sdIdentityEntry(){
                                Class = enumFasdInformationClass.User,
                                Id = Guid.Parse(constGuidVeraVirtuell)
                        }
                    }
                    });

                    output.Add(new cF4sdApiSearchResultRelation()
                    {
                        id = Guid.Parse(constGuidVeraVirtuell),
                        Name = "VM-W11MS05",
                        DisplayName = "VM-W11MS05",
                        LastUsed = DateTime.UtcNow.AddDays(-5),
                        Type = enumF4sdSearchResultClass.VirtualSession,
                        UsingLevel = 0.14,
                        Status = enumF4sdSearchResultStatus.Inactive,
                        Infos = new Dictionary<string, string>()
                        {
                            ["Status"] = enumF4sdSearchResultStatus.Inactive.ToString()
                        },
                        Identities = new cF4sdIdentityList()
                        {
                            new cF4sdIdentityEntry(){
                                Class = enumFasdInformationClass.VirtualSession,
                                Id = Guid.Parse(constGuidVeraVirtuell)
                            },
                            new cF4sdIdentityEntry(){
                                Class = enumFasdInformationClass.User,
                                Id = Guid.Parse(constGuidVeraVirtuell)
                        }
                    }
                    });

                    break;
                case constGuidPeterAnwender: // Peter Anwender
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4-AP00007", DisplayName = "C4-AP00007", Infos = new Dictionary<string, string>() { ["UserAccountType"] = "AD", ["UserAccount"] = "AP007", ["UserDomain"] = "C4IT" }, LastUsed = DateTime.UtcNow.AddSeconds(-31), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = Guid.Parse(constGuidPeterAnwender) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4-NB00107", DisplayName = "C4-NB00107", Infos = new Dictionary<string, string>() { ["UserAccountType"] = "AD", ["UserAccount"] = "AP007", ["UserDomain"] = "C4IT-old" }, LastUsed = DateTime.UtcNow.AddDays(-10), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 0.2, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = Guid.Parse(constGuidPeterAnwender) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4-NB00015", DisplayName = "C4-NB00015", Infos = new Dictionary<string, string>() { ["UserAccountType"] = "Local", ["UserAccount"] = "AP007" }, LastUsed = DateTime.UtcNow.AddHours(-10), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 0.6, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = Guid.Parse(constGuidPeterAnwender) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
                    break;
                case constGuidMischaMobile: // Mischa MObile
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4-MM007", DisplayName = "C4-MM007", Infos = new Dictionary<string, string>() { ["UserAccountType"] = "AD", ["UserAccount"] = "AP007", ["UserDomain"] = "C4IT" }, LastUsed = DateTime.UtcNow.AddSeconds(-31), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.Parse(constGuidMischaMobile) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4-NB005", DisplayName = "C4-NB005", Infos = new Dictionary<string, string>() { ["UserAccountType"] = "AD", ["UserAccount"] = "C4-NB005", ["UserDomain"] = "C4IT" }, LastUsed = DateTime.UtcNow.AddDays(-10), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.Parse(constGuidMischaMobile) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });

                    output.Add(new cF4sdApiSearchResultRelation()
                    {
                        id = Guid.NewGuid(),
                        Name = "IPad-C7JXH5B69P",
                        DisplayName = "IPad-C7JXH5B69P",
                        LastUsed = DateTime.UtcNow.AddHours(-3),
                        Type = enumF4sdSearchResultClass.MobileDevice,
                        UsingLevel = 1,
                        Identities = new cF4sdIdentityList()
                        {
                            new cF4sdIdentityEntry(){
                                Class = enumFasdInformationClass.User,
                                Id = Guid.Parse(constGuidMischaMobile)
                            },
                            new cF4sdIdentityEntry(){
                                Class = enumFasdInformationClass.MobileDevice,
                                Id = Guid.NewGuid()
                        }
                    }
                    });
                    break;
                case constGuidCarlos: // Carlos
                case constGuidPaulPerschmann: // Paul Perschmann
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "VM-PP00123", DisplayName = "VM-PP00123", LastUsed = DateTime.UtcNow.AddDays(-10), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = resultIds.First() }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "VM-PP00124", DisplayName = "VM-PP00124", LastUsed = DateTime.UtcNow.AddDays(-5), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = resultIds.First() }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "VM-PP00125", DisplayName = "VM-PP00125", LastUsed = DateTime.UtcNow.AddDays(-31), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = resultIds.First() }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "Client-PP1003", DisplayName = "Client-PP1003", LastUsed = DateTime.UtcNow, Type = enumF4sdSearchResultClass.User, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = resultIds.First() }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
                    break;
                case constGuidCarlKriminell:
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4-CK007", DisplayName = "C4-CK007", LastUsed = DateTime.UtcNow, Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = resultIds.First() }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
                    break;
                case constGuidTimoTicket:
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.Parse(constGuidTimoTicketComputer), Name = "C4-TT007", DisplayName = "C4-TT007", LastUsed = DateTime.UtcNow.AddSeconds(-31), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = Guid.Parse(constGuidTimoTicket) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.Parse(constGuidTimoTicketComputer) } }, Infos = new Dictionary<string, string>() });
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4-NB00015", DisplayName = "C4-NB00015", LastUsed = DateTime.UtcNow.AddHours(-10), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 0.6, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = Guid.Parse(constGuidTimoTicket) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } }, Infos = new Dictionary<string, string>() });

                    var demoTickets = await GetDemoTicketData(new cF4sdHealthCardRawDataRequest() { Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = Guid.Parse(constGuidTimoTicket) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });

                    foreach (var demoTicket in demoTickets)
                    {
                        output.Add(new cF4sdApiSearchResultRelation() { id = demoTicket.Id, Name = demoTicket.Name, DisplayName = demoTicket.Name, Infos = new Dictionary<string, string>() { ["Summary"] = demoTicket.Summary, ["Status"] = demoTicket.Status.ToString(), ["StatusId"] = ((int)demoTicket.Status).ToString(), ["Asset"] = demoTicket.Asset, ["ActivityType"] = demoTicket.ActivityType }, Type = enumF4sdSearchResultClass.Ticket, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = Guid.Parse(constGuidTimoTicket) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Ticket, Id = demoTicket.Id } } });
                    }

                    break;
                case constGuidTimoTicketComputer:
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.Parse(constGuidTimoTicketComputer), Name = "C4-TT007", DisplayName = "C4-TT007", LastUsed = DateTime.UtcNow.AddSeconds(-31), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = Guid.Parse(constGuidTimoTicket) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.Parse(constGuidTimoTicketComputer) } } });
                    break;
                case constGuidFraukeNichtAnwender: // Frauke Nicht Anwender
                case constGuidComputer: // Computer
                    break;
                default:
                    output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4IT-007", DisplayName = "C4IT-007", LastUsed = DateTime.UtcNow, Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = resultIds.First() }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
                    break;
            }

            if (resultType == enumF4sdSearchResultClass.User)
            {
                foreach (var userId in resultIds)
                {
                    AppendDemoTicketRelationsForUser(userId, output);
                }
            }

            await Task.CompletedTask;

            output = output.OrderByDescending(relation => relation.LastUsed).ToList();
            return output;
        }

        private void AppendDemoTicketRelationsForUser(Guid userId, List<cF4sdApiSearchResultRelation> output)
        {
            if (userId == Guid.Empty || output == null)
                return;

            var selectedData = MockupData.FirstOrDefault(data => data?.SampleDataId == userId);
            if (selectedData?.Tickets == null)
                return;

            foreach (var demoTicket in selectedData.Tickets)
            {
                if (demoTicket == null || demoTicket.Id == Guid.Empty)
                    continue;

                if (output.Any(relation => relation.Type == enumF4sdSearchResultClass.Ticket && relation.id == demoTicket.Id))
                    continue;

                output.Add(new cF4sdApiSearchResultRelation()
                {
                    id = demoTicket.Id,
                    Name = demoTicket.Name,
                    DisplayName = demoTicket.Name,
                    LastUsed = demoTicket.CreationDate == default ? DateTime.UtcNow : demoTicket.CreationDate.ToUniversalTime(),
                    Type = enumF4sdSearchResultClass.Ticket,
                    UsingLevel = 1,
                    Infos = new Dictionary<string, string>()
                    {
                        ["Summary"] = demoTicket.Summary ?? string.Empty,
                        ["Status"] = demoTicket.Status.ToString(),
                        ["StatusId"] = ((int)demoTicket.Status).ToString(),
                        ["Asset"] = demoTicket.Asset ?? string.Empty,
                        ["ActivityType"] = demoTicket.ActivityType
                    },
                    Identities = new cF4sdIdentityList()
                    {
                        new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = userId },
                        new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Ticket, Id = demoTicket.Id }
                    }
                });
            }
        }

        public override async Task<cF4SDHealthCardRawData> GetHealthCardData(cF4sdHealthCardRawDataRequest requestData)
        {
            var CM = MethodBase.GetCurrentMethod();
            LogMethodBegin(CM);

            var output = new cF4SDHealthCardRawData();
            cF4SDHealthCardRawData.cHealthCardTable outputTable;

            try
            {
                await Task.Delay(250);

                var selectedData = MockupData.FirstOrDefault(data => requestData.Identities.Any(identity => identity.Id == data.SampleDataId));

                if (selectedData is null)
                    return output;

                output = selectedData.GetHealthCardData();
                var ticketRequest = requestData.Identities.FirstOrDefault(data => data.Class is enumFasdInformationClass.Ticket);
                if (ticketRequest != null)
                {
                    var selectedTicket = selectedData.Tickets.FirstOrDefault(ticket => ticket.Id == ticketRequest.Id);

                    if (selectedTicket != null)
                    {
                        string ticketStatusString = string.Empty;
                        switch (selectedTicket.Status)
                        {
                            case enumTicketStatus.Unknown:
                                ticketStatusString = "Unbekannt";
                                break;
                            case enumTicketStatus.New:
                                ticketStatusString = "Neu";
                                break;
                            case enumTicketStatus.InProgress:
                                ticketStatusString = "Offen";
                                break;
                            case enumTicketStatus.Closed:
                                ticketStatusString = "Geschlossen";
                                break;
                        }


                        outputTable = new cF4SDHealthCardRawData.cHealthCardTable()
                        {
                            Name = "M42Wpm-Tickets",
                            InformationClass = enumFasdInformationClass.Ticket,
                            IsStatic = true,
                        };

                        outputTable.Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>()
                        {
                            ["name"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.Name } },
                            ["Status"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { ticketStatusString } },
                            ["Priority"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.Priority } },
                            ["AffectedUser"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.AffectedUser } },
                            ["AssetName"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.Asset } },
                            ["CreationDaysSinceNow"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.CreationDaysSinceNow } },
                            ["CreationDate"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.CreationDate.ToUniversalTime() } },
                            ["ClosingDaysSinceNow"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.ClosingDaysSinceNow } },
                            ["ClosingDate"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.ClosingDate } },
                            ["Category"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { ResolveCategoryDisplayName(selectedTicket.Category) } },
                            ["CategoryId"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.Category } },
                            ["CreationSource"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.CreationSource.ToString() } },
                            ["Description"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.Description?.ToString() } },
                            ["DescriptionHtml"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.DescriptionHtml?.ToString() } },
                            ["Summary"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.Summary.ToString() } },
                            ["Solution"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.Solution?.ToString() } },
                            ["SolutionHtml"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { Values = new List<object>() { selectedTicket.SolutionHtml?.ToString() } },
                        };

                        output.Tables["M42Wpm-Tickets"] = outputTable;

                        outputTable = new cF4SDHealthCardRawData.cHealthCardTable()
                        {
                            Name = "M42Wpm-Ticket-History",
                            InformationClass = enumFasdInformationClass.Ticket,
                            IsStatic = false
                        };
                        outputTable.Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>()
                        {
                            ["Header"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable),
                            ["IsVisibleForUser"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable),
                            ["CreationDaysSinceNow"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable),
                            ["time"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable),
                            ["Description"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable),
                            ["DescriptionHtml"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable)
                        };

                        output.Tables["M42Wpm-Ticket-History"] = outputTable;

                        foreach (var journalItem in selectedTicket.JournalItems)
                        {
                            output.Tables["M42Wpm-Ticket-History"].Columns["Header"].Values.Add(journalItem.Header);
                            output.Tables["M42Wpm-Ticket-History"].Columns["IsVisibleForUser"].Values.Add(journalItem.IsVisibleForUser);
                            output.Tables["M42Wpm-Ticket-History"].Columns["CreationDaysSinceNow"].Values.Add(journalItem.CreationDaysSinceNow);
                            output.Tables["M42Wpm-Ticket-History"].Columns["time"].Values.Add(journalItem.CreationDate.ToUniversalTime());
                            output.Tables["M42Wpm-Ticket-History"].Columns["Description"].Values.Add(journalItem.Description);
                            output.Tables["M42Wpm-Ticket-History"].Columns["DescriptionHtml"].Values.Add(journalItem.DescriptionHtml);
                        }

                        foreach (var directLink in selectedTicket.DirectLinks)
                        {
                            outputTable = output.Tables["M42Wpm-Tickets"];
                            if (outputTable?.Columns != null)
                                outputTable.Columns[directLink.Key] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable) { ColumnName = directLink.Key, IsIncomplete = false, Values = new List<object>() { directLink.Value } };
                        }
                    }
                }

                outputTable = new cF4SDHealthCardRawData.cHealthCardTable()
                {
                    IsIncomplete = true,
                    IsStatic = false,
                    StartingIndex = 7
                };
                outputTable.Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>()
                {
                    ["sequenceColumn"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable)
                    {
                        ColumnName = "sequenceColumn",
                        Values = new List<object>() { 1, 0 }
                    }
                };

                output.Tables.Add("sequenceTable", outputTable);

                outputTable = new cF4SDHealthCardRawData.cHealthCardTable()
                {
                    IsIncomplete = true,
                    IsStatic = false,
                    StartingIndex = 7
                };
                outputTable.Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>()
                {
                    ["sequenceColumn"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable)
                    {
                        ColumnName = "sequenceColumn",
                        Values = new List<object>() { 8, 1, 0 }
                    }
                };

                output.Tables.Add("sequenceTable2", outputTable);

                outputTable = new cF4SDHealthCardRawData.cHealthCardTable()
                {
                    IsIncomplete = false,
                    StartingIndex = 0,
                    IsStatic = true
                };
                outputTable.Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>()
                {
                    ["sequenceColumn"] = new cF4SDHealthCardRawData.cHealthCardTableColumn(outputTable)
                    {
                        ColumnName = "sequenceColumn",
                        Values = new List<object>() { "Static" }
                    }
                };

                output.Tables.Add("sequenceTable3", outputTable);

                output.Id = Guid.NewGuid();

                var task = Task.Run(() => LoadSequenceTables(output.Id));

                // get the remaining tables from the mockup pickup data

                foreach (var _entry in requestData.Tables)
                {
                    if (output.Tables.ContainsKey(_entry))
                        continue;

                    if (!MockupPickup.TryGetValue(_entry, out var _table))
                        continue;

                    output.Tables.Add(_entry, _table);

                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                LogMethodEnd(CM);
            }

            await Task.CompletedTask;

            var outputString = JsonConvert.SerializeObject(output);

            var retVal = JsonConvert.DeserializeObject<cF4SDHealthCardRawData>(outputString);

            return retVal;
        }

        private async void LoadSequenceTables(Guid Id)
        {
            try
            {
                const string tableOne = "sequenceTable";
                const string tableTwo = "sequenceTable2";
                const string columnName = "sequenceColumn";

                await Task.Delay(250);
                lock (CachedHealthCardRawData)
                {
                    if (!CachedHealthCardRawData.TryGetValue(Id, out var _rawData))
                    {
                        _rawData = new cF4SDHealthCardRawData() { Id = Id, Tables = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>() };
                        CachedHealthCardRawData[Id] = _rawData;
                    }

                    if (_rawData.Tables is null)
                        _rawData.Tables = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>();

                    if (!_rawData.Tables.TryGetValue(tableOne, out var _table))
                    {
                        _table = new cF4SDHealthCardRawData.cHealthCardTable() { Name = tableOne, Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>() };
                        _rawData.Tables[tableOne] = _table;
                    }

                    if (!_table.Columns.ContainsKey(columnName))
                        _table.Columns[columnName] = new cF4SDHealthCardRawData.cHealthCardTableColumn(_table);

                    _table.StartingIndex = 3;
                    _table.IsIncomplete = true;

                    if (_table.Columns[columnName].Values.Count < 3)
                        _table.Columns[columnName].Values.AddRange(new List<object>() { 5, 4, 3, 2, 1, 0 });
                    else
                        _table.Columns[columnName].Values.InsertRange(3, new List<object>() { 5, 4, 3, 2, 1, 0 });
                }

                await Task.Delay(250);
                lock (CachedHealthCardRawData)
                {
                    if (!CachedHealthCardRawData.TryGetValue(Id, out var _rawData))
                    {
                        _rawData = new cF4SDHealthCardRawData() { Id = Id, Tables = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>() };
                        CachedHealthCardRawData[Id] = _rawData;
                    }

                    if (_rawData.Tables is null)
                        _rawData.Tables = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>();

                    if (!_rawData.Tables.TryGetValue(tableTwo, out var _table))
                    {
                        _table = new cF4SDHealthCardRawData.cHealthCardTable() { Name = tableTwo, Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>() };
                        _rawData.Tables[tableTwo] = _table;
                    }

                    if (!_table.Columns.ContainsKey(columnName))
                        _table.Columns[columnName] = new cF4SDHealthCardRawData.cHealthCardTableColumn(_table);

                    _table.StartingIndex = 2;
                    _table.IsIncomplete = true;

                    if (_table.Columns[columnName].Values.Count < 2)
                        _table.Columns[columnName].Values.AddRange(new List<object>() { 0, 3, 1, 2, 3, 8, 1, 0 });
                    else
                        _table.Columns[columnName].Values.InsertRange(2, new List<object>() { 0, 3, 1, 2, 3, 8, 1, 0 });
                }

                await Task.Delay(500);
                lock (CachedHealthCardRawData)
                {
                    const string numericalTable = "agnt-computer-event-numerical";
                    const string processorColumn = "ProcessorUsage";

                    if (!CachedHealthCardRawData.TryGetValue(Id, out var _rawData))
                    {
                        _rawData = new cF4SDHealthCardRawData() { Id = Id, Tables = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>() };
                        CachedHealthCardRawData[Id] = _rawData;
                    }

                    if (_rawData.Tables is null)
                        _rawData.Tables = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>();

                    if (!_rawData.Tables.TryGetValue(numericalTable, out var _table))
                    {
                        _table = new cF4SDHealthCardRawData.cHealthCardTable() { Name = numericalTable, Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>() };
                        _rawData.Tables[numericalTable] = _table;
                    }

                    if (!_table.Columns.ContainsKey(processorColumn))
                        _table.Columns[processorColumn] = new cF4SDHealthCardRawData.cHealthCardTableColumn(_table);

                    _table.IsIncomplete = false;
                    _table.Columns[processorColumn].IsIncomplete = false;
                    _table.Columns[processorColumn].Values = new List<object>() { 12.0, 20.0, 18.0, 15.0, 18.0, 19.0, 20.0, 26.0, 17.0, 11.0, 18.0, 16.0, 16.0, 14.0, 15.0 };
                }

                await Task.Delay(250);
                lock (CachedHealthCardRawData)
                {
                    if (!CachedHealthCardRawData.TryGetValue(Id, out var _rawData))
                    {
                        _rawData = new cF4SDHealthCardRawData() { Id = Id, Tables = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>() };
                        CachedHealthCardRawData[Id] = _rawData;
                    }

                    if (_rawData.Tables is null)
                        _rawData.Tables = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>();

                    if (!_rawData.Tables.TryGetValue(tableOne, out var _table))
                    {
                        _table = new cF4SDHealthCardRawData.cHealthCardTable() { Name = tableOne, Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>() };
                        _rawData.Tables[tableOne] = _table;
                    }

                    if (!_table.Columns.TryGetValue(columnName, out var _column))
                    {
                        _column = new cF4SDHealthCardRawData.cHealthCardTableColumn(_table);
                        _table.Columns[columnName] = _column;
                    }

                    _table.StartingIndex = 0;
                    _table.IsIncomplete = false;

                    if (_column.Values.Count < 0)
                        _column.Values.AddRange(new List<object>() { 8, 7, 6 });
                    else
                        _column.Values.InsertRange(0, new List<object>() { 8, 7, 6 });


                    if (!_rawData.Tables.TryGetValue(tableTwo, out var _table2))
                    {
                        _table2 = new cF4SDHealthCardRawData.cHealthCardTable() { Name = tableTwo, Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>() };
                        _rawData.Tables[tableTwo] = _table2;
                    }

                    if (!_rawData.Tables[tableTwo].Columns.ContainsKey(columnName))
                        CachedHealthCardRawData[Id].Tables[tableTwo].Columns[columnName] = new cF4SDHealthCardRawData.cHealthCardTableColumn(_table2);

                    _table2.StartingIndex = 1;
                    _table2.IsIncomplete = false;


                    if (_table2.Columns[columnName].Values.Count < 1)
                        _table2.Columns[columnName].Values.AddRange(new List<object>() { 1 });
                    else
                        _table2.Columns[columnName].Values.InsertRange(1, new List<object>() { 1 });
                }


            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        public override async Task<cF4SDHealthCardRawData> GetHealthCardData(Guid healthCardId)
        {
            cF4SDHealthCardRawData healthcardData = null;

            try
            {
                await Task.Delay(50);

                lock (CachedHealthCardRawData)
                {
                    if (CachedHealthCardRawData.TryGetValue(healthCardId, out healthcardData))
                        return healthcardData;
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }

            return healthcardData;
        }

        public override async Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>> GetDetailsData(cF4sdHealthCardRawDataRequest requestData)
        {
            var output = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();

            try
            {
                var selectedData = MockupData.FirstOrDefault(data => requestData.Identities.Any(identity => identity.Id == data.SampleDataId));
                output = selectedData.DetailsTables;
            }
            catch (Exception E)
            {
                LogException(E);
            }

            await Task.CompletedTask;
            return output;
        }

        private SortedList<int, object> FilterColumData(string search, string ColName, cF4SDHealthCardRawData.cHealthCardTable table)
        {
            var retVal = new SortedList<int, object>();

            if (table.Columns.TryGetValue(ColName, out var column))
            {
                for (int i = 0; i < column.Values.Count; i++)
                {
                    if (column.Values[i].ToString().ToLowerInvariant().Contains(search.ToLowerInvariant()))
                        retVal.Add(i, null);
                }
            }
            return retVal;
        }

        private SortedList<int, object> FilterTableData(string search, cF4SDHealthCardRawData.cHealthCardTable table)
        {
            var retVal = FilterColumData(search, "DisplayName", table);
            var l2 = FilterColumData(search, "Name", table);
            foreach (var row in l2.Keys)
                retVal[row] = null;
            return retVal;
        }

        public override async Task<int> GetPagedDataCount(cF4sdHealthSelectionDataRequest requestData)
        {
            var CM = MethodBase.GetCurrentMethod();
            LogMethodBegin(CM);
            try
            {
                await Task.CompletedTask;

                if (!MockupPickup.TryGetValue(requestData.Table, out var _result))
                    return 0;

                if (_result?.Columns == null || _result.Columns.Count <= 0)
                    return 0;

                var _vals = _result.Columns.First().Value.Values;
                if (_vals == null)
                    return 0;

                int retVal = 0;
                if (string.IsNullOrEmpty(requestData.Search))
                    retVal = _vals.Count;
                else
                {
                    var l = FilterTableData(requestData.Search, _result);
                    retVal = l.Count;
                }

                return retVal;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                LogMethodEnd(CM);
            }

            return 0;
        }

        public override async Task<cF4SDHealthCardRawData.cHealthCardTable> GetPagedData(cF4sdHealthSelectionDataRequest requestData)
        {
            var CM = MethodBase.GetCurrentMethod();
            LogMethodBegin(CM);
            try
            {
                await Task.CompletedTask;

                if (!MockupPickup.TryGetValue(requestData.Table, out var _result))
                    return null;

                var _s = JsonConvert.SerializeObject(_result);
                var _resultCopy = JsonConvert.DeserializeObject<cF4SDHealthCardRawData.cHealthCardTable>(_s);

                if (_resultCopy.Columns == null)
                    return null;

                if (!string.IsNullOrEmpty(requestData.Search))
                {
                    var colIndexes = FilterTableData(requestData.Search, _result);
                    foreach (var _entry in _resultCopy.Columns.Values)
                    {
                        var _values = new List<object>(colIndexes.Count);
                        foreach (var _index in colIndexes.Keys)
                        {
                            if (_index <= _entry.Values.Count)
                                _values.Add(_entry.Values[_index]);
                        }
                        _entry.Values = _values;
                    }
                }

                foreach (var _entry in _resultCopy.Columns.Values)
                {
                    if (_entry.Values == null) continue;
                    var c = _entry.Values.Count;
                    var c2 = (requestData.Page + 1) * requestData.PageSize;
                    if (c2 > c) c2 = c;
                    int n = c2 - requestData.Page * requestData.PageSize;
                    var newValues = new List<object>();
                    for (int i = requestData.Page * requestData.PageSize; i < c2; i++)
                        newValues.Add(_entry.Values[i]);
                    _entry.Values = newValues;
                }


                return _resultCopy;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                LogMethodEnd(CM);
            }

            return null;
        }

        private cF4SDTicket GetTicketFromWriteParameter(cF4SDWriteParameters writeParams)
        {
            cF4SDTicket output = null;

            try
            {
                output = new cF4SDTicket()
                {
                    Id = writeParams.id,
                    DirectLinks = new Dictionary<string, string>(),
                    JournalItems = new List<cF4SDTicket.cTicketJournalItem>()
                };

                if (writeParams.Values.TryGetValue("Summary", out var summary))
                    output.Summary = summary.ToString();

                if (writeParams.Values.TryGetValue("Description", out var description))
                    output.Description = description.ToString();

                if (writeParams.Values.TryGetValue("DescriptionHtml", out var descriptionHtml))
                    output.DescriptionHtml = descriptionHtml.ToString();

                if (writeParams.Values.TryGetValue("AffectedUser", out var affectedUser))
                    output.AffectedUser = affectedUser.ToString();

                if (writeParams.Values.TryGetValue("Asset", out var asset))
                    output.Asset = asset.ToString();

                if (writeParams.Values.TryGetValue("Category", out var category))
                    output.Category = category.ToString();

                if (writeParams.Values.TryGetValue("ActivityType", out var activityType))
                    output.ActivityType = activityType?.ToString()?.Trim();

                if (writeParams.Values.TryGetValue("CreationSource", out var creationSourceObj))
                    if (Enum.TryParse(creationSourceObj.ToString(), out cF4SDTicket.enumTicketCreationSource creationSource))
                        output.CreationSource = creationSource;

                if (writeParams.Values.TryGetValue("Status", out var statusObj))
                {
                    if (Enum.TryParse(statusObj.ToString(), out enumTicketStatus ticketStatus))
                        output.Status = ticketStatus;
                    else if (statusObj is enumTicketStatus ticketStatusEnum)
                        output.Status = ticketStatusEnum;
                }

                if (writeParams.Values.TryGetValue("Priority", out var priorityObj))
                    if (int.TryParse(priorityObj.ToString(), out int priority))
                        output.Priority = priority;

                if (writeParams.Values.TryGetValue("ClosingDate", out var closingDateObj))
                {
                    if (closingDateObj is DateTime closingDate)
                    {
                        output.ClosingDate = closingDate.ToLocalTime();
                        output.ClosingDaysSinceNow = (DateTime.UtcNow - closingDate).Days;
                    }
                }

                if (writeParams.Values.TryGetValue("Solution", out var solution))
                    output.Solution = solution.ToString();

                if (writeParams.Values.TryGetValue("SolutionHtml", out var solutionHtml))
                    output.SolutionHtml = solutionHtml.ToString();
            }
            catch (Exception E)
            {
                LogException(E);
            }

            return output;
        }

        private bool AddDemoTicketFromWriteParameter(cF4SDWriteParameters dataParameter)
        {
            try
            {
                var ticketFromParameter = GetTicketFromWriteParameter(dataParameter);

                if (ticketFromParameter is null)
                    return false;

                var selectedTicket = MockupData
                    .FirstOrDefault(data => data.Tickets.Any(ticket => ticket.Id == dataParameter.id))?.Tickets
                    .FirstOrDefault(ticket => ticket.Id == dataParameter.id);

                if (selectedTicket != null)
                {
                    selectedTicket = ticketFromParameter;
                    return true;
                }

                if (!dataParameter.Values.TryGetValue("UserId", out var userId))
                    return false;

                var selectedSampleData = MockupData.FirstOrDefault(data => data.SampleDataId.Equals(userId));

                if (selectedSampleData is null)
                    return false;

                if (dataParameter.Values.TryGetValue("TicketId", out var ticketIdValue))
                    if (ticketIdValue is Guid ticketId)
                        ticketFromParameter.Id = ticketId;

                ticketFromParameter.Name = "INC00" + ticketCounter++;
                ticketFromParameter.CreationDate = DateTime.UtcNow;
                ticketFromParameter.CreationDaysSinceNow = 0;

                selectedSampleData.Tickets.Add(ticketFromParameter);
            }
            catch (Exception E)
            {
                LogException(E);
            }

            return false;
        }

        private cF4SDTicket.cTicketJournalItem GetJournalItemFromWriteParameter(cF4SDWriteParameters writeParams)
        {
            cF4SDTicket.cTicketJournalItem output = null;

            try
            {
                output = new cF4SDTicket.cTicketJournalItem();

                if (writeParams.Values.TryGetValue("Header", out var header))
                    output.Header = header.ToString();

                if (writeParams.Values.TryGetValue("IsVisibleForUser", out var isVisibleForUserValue))
                    if (isVisibleForUserValue is bool isVisibleForUser)
                        output.IsVisibleForUser = isVisibleForUser;

                if (writeParams.Values.TryGetValue("time", out var timeValue))
                {
                    if (timeValue is DateTime time)
                    {
                        output.CreationDate = time;
                        output.CreationDaysSinceNow = (DateTime.UtcNow - time).Days;
                    }
                }

                if (writeParams.Values.TryGetValue("Description", out var description))
                    output.Description = description.ToString();

                if (writeParams.Values.TryGetValue("DescriptionHtml", out var descriptionHtml))
                    output.DescriptionHtml = descriptionHtml.ToString();
            }
            catch (Exception E)
            {
                LogException(E);
            }

            return output;
        }

        private bool AddDemoJournalItemFromWriteParameter(cF4SDWriteParameters dataParameter)
        {
            try
            {
                var selectedTicket = MockupData
                    .FirstOrDefault(data => data.Tickets.Any(ticket => ticket.Id == dataParameter.id))?.Tickets
                    .FirstOrDefault(ticket => ticket.Id == dataParameter.id);

                if (selectedTicket is null)
                {
                    if (!dataParameter.Values.TryGetValue("TicketId", out var ticketIdValue))
                        return false;

                    selectedTicket = MockupData
                        .FirstOrDefault(data => data.Tickets.Any(ticket => ticket.Id == dataParameter.id))?.Tickets
                        .FirstOrDefault(ticket => ticket.Id.Equals(ticketIdValue));
                }

                if (selectedTicket is null)
                    return false;

                var journalItemFromParam = GetJournalItemFromWriteParameter(dataParameter);
                if (journalItemFromParam is null)
                    return false;

                selectedTicket.JournalItems.Add(journalItemFromParam);
                return true;
            }
            catch (Exception E)
            {
                LogException(E);
            }

            return false;
        }

        public override Task<bool> UpdateHealthcardTableData(cF4SDWriteParameters dataParameter)
        {
            try
            {
                if (dataParameter.TableName == "M42Wpm-Tickets")
                    return Task.FromResult(AddDemoTicketFromWriteParameter(dataParameter));
                else if (dataParameter.TableName == "M42Wpm-Tickets-History")
                    return Task.FromResult(AddDemoJournalItemFromWriteParameter(dataParameter));
            }
            catch (Exception E)
            {
                LogException(E);
            }

            return Task.FromResult(false);
        }

        public override Task<bool> Matrix42TicketFinalization(cApiM42Ticket ticketData) => Task.FromResult(true);

        private async Task<List<cF4SDTicket>> GetDemoTicketData(cF4sdHealthCardRawDataRequest requestData)
        {
            await Task.CompletedTask;
            var output = new List<cF4SDTicket>();
            try
            {
                var selectedData = MockupData.FirstOrDefault(data => requestData.Identities.Any(identity => identity.Id == data.SampleDataId));

                if (selectedData is null)
                    return output;

                output = selectedData.Tickets ?? output;
            }
            catch (Exception E)
            {
                LogException(E);
            }

            return output;
        }

        public async Task<List<cF4SDTicketSummary>> GetTicketSummaries(cF4sdHealthCardRawDataRequest requestData)
        {

            var output = new List<cF4SDTicketSummary>();
            try
            {
                var demoTickets = await GetDemoTicketData(requestData);
                foreach (var ticket in demoTickets)
                {
                    output.Add(new cF4SDTicketSummary()
                    {
                        Id = ticket.Id,
                        Name = ticket.Name,
                        Status = ticket.Status,
                        Summary = ticket.Summary
                    });
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
            return output;
        }

        public override Task<List<List<object>>> GetQuickActionHistory(string QuickActionName, int OrgId, int DeviceId, int? UserId) => Task.FromResult(new List<List<object>>());


        public override async Task<bool> GetAgentApiAccessInfo()
        {
            cCockpitConfiguration.Instance = new cCockpitConfiguration();
            cCockpitConfiguration.Instance.agentApiConfiguration = new cAgentApiConfiguration() { ApiUrl = "", ClientId = "", ClientSecret = "", LogonUrl = "", OrganizationCode = 0 };
            await Task.CompletedTask;
            return true;
        }

        public override async Task<bool> GetCockpitConfiguration()
        {
            cCockpitConfiguration.Instance = new cCockpitConfiguration();
            cCockpitConfiguration.Instance.agentApiConfiguration = new cAgentApiConfiguration() { ApiUrl = "", ClientId = "", ClientSecret = "", LogonUrl = "", OrganizationCode = 0 };
            cCockpitConfiguration.Instance.m42ServerConfiguration = new cM42ServerConfiguration() { Server = "https://srvwsm001.imagoverum.com" };
            cCockpitConfiguration.Instance.GlobalConfig = null;
            await Task.CompletedTask;
            return true;
        }

        public override Task<bool> GetAgentOnlineStatus(int AgentDeviceId, int? AgentUserId = null) => Task.FromResult(true);

        public override Task<cF4sdAgentScript> GetQuickActionOfAgent(int ScriptId) => Task.FromResult(new cF4sdAgentScript() { Id = ScriptId, Name = "AgentScript", Type = enumAgentScriptType.user, UserPermissionRequired = false });

        public override Task<List<cF4sdAgentScript>> GetQuickActionsOfAgent() => Task.FromResult(new List<cF4sdAgentScript>());

        public override Task<Guid> ActualizeAgentData(int AgentDeviceId, int? AgentUserId = null) => Task.FromResult(Guid.NewGuid());

        public override async Task<enumActualizeStatus> GetActualizeAgentDataStatus(Guid actualizeId, enumFasdInformationClass informationClass)
        {
            await Task.Delay(2500);
            return enumActualizeStatus.successfull;
        }

        public override async Task<Guid?> TryActivateDirectConnection(int DeviceId)
        {
            await Task.Delay(5000);
            return Guid.NewGuid();
        }

        public override Task StopDirectConnection(Guid connectionId) => Task.CompletedTask;

        public override Task<bool> IsDirectConnectionUp(Guid connectionId) => Task.FromResult(true);

        public override Task<bool> DirectConnectionExtendDuration(Guid connectonId, int timeOutInMilliseconds) => Task.FromResult(true);

        public override Task<cF4sdAgentScriptInformation> RunAgentScript(cF4sdQuickActionRemote Script, int OrgCode, int DeviceId, int? DeviceAccountId, string Parameters) => Task.FromResult(new cF4sdAgentScriptInformation() { RevisionId = int.MinValue });

        public override Task<cF4sdQuickActionRevision> GetAgentRevision(int RevisionId, int OrgId) => Task.FromResult<cF4sdQuickActionRevision>(null);

        public override Task<enumQuickActionStatus> GetAgentQuickActionStatus(int TaskId) => Task.FromResult(enumQuickActionStatus.Finished);

        public override Task CancelAgentTask(int TaskId) => Task.CompletedTask;

        public override Task<List<string>> GetQuickActionsOfServer() => Task.FromResult<List<string>>(null);

        public override Task<cF4sdStagedSearchResultRelationTaskId> StartGatheringRelations(IEnumerable<cFasdApiSearchResultEntry> relatedTo, CancellationToken token) => Task.FromResult(new cF4sdStagedSearchResultRelationTaskId() { Id = relatedTo.FirstOrDefault().id, PendingInformationClasses = new HashSet<enumFasdInformationClass>() { enumFasdInformationClass.User, enumFasdInformationClass.Computer, enumFasdInformationClass.Ticket, enumFasdInformationClass.VirtualSession, enumFasdInformationClass.MobileDevice } });

        public override async Task<cF4sdStagedSearchResultRelations> GetStagedRelations(Guid id, CancellationToken token)
        {
            await Task.Delay(1500);
            List<cF4sdApiSearchResultRelation> relations = await GetSearchResultRelations(enumF4sdSearchResultClass.User, new List<cFasdApiSearchResultEntry>() { new cFasdApiSearchResultEntry() { id = id } });
            return new cF4sdStagedSearchResultRelations() { Relations = relations };
        }

        private async Task DoLocalQuickActionAsync(string ActionPrefix, string ActionNaming)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }

            try
            {
                if (cF4SDCockpitXmlConfig.Instance?.QuickActionConfig?.F4SDQuickActions?.QuickActions == null)
                    return;

                ActionPrefix = ActionPrefix.ToLowerInvariant();
                foreach (var _quickAction in cF4SDCockpitXmlConfig.Instance.QuickActionConfig.F4SDQuickActions.QuickActions.Values)
                {
                    if (!(_quickAction is cFasdQuickActionLocalScript _localAction))
                        continue;

                    if (!_localAction.Name.ToLowerInvariant().StartsWith(ActionPrefix))
                        continue;

                    Debug.WriteLine($"Starting Demo {ActionNaming} Quick Action {_localAction.Name}.");

                    await cExternalToolExecutor.StartLocalActionAsync(_localAction, null, null);
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                if (CM != null) LogMethodEnd(CM);
            }
        }

        public override async Task InitializeAfterOnlineAsync()
        {
            await DoLocalQuickActionAsync("DemoInitialization", "Initialization");
        }


        public override async Task TerminateAsync()
        {
            await DoLocalQuickActionAsync("DemoTermination", "Termination");
        }

        public override Uri GetMediaContentUri(string ContentRelPath)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }

            try
            {
                var _path = Assembly.GetExecutingAssembly().Location;
                _path = System.IO.Path.GetDirectoryName(_path);
                var _mediaUriBuilder = new UriBuilder(_path + "\\");
                var _mediaUri = new Uri(_mediaUriBuilder.Uri, ContentRelPath);

                return _mediaUri;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                if (CM != null) LogMethodEnd(CM);
            }

            return null;
        }

        public override Task<cCollectorStatusInfo> CheckCollectorStatusAsync()
        {
            throw new NotImplementedException();
        }
    }
}
