using C4IT.LIAM;
using C4IT.Logging;
using C4IT.MsGraph;
using C4IT_IAM_Engine;
using LiamAD;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using static C4IT.Logging.cLogManager;
using static LiamAD.ADServiceGroupCreator;

namespace LiamWorkflowActivities
{
    public class GetDataAreasOperationResult
    {
        public bool Success { get; set; }
        public string ErrorCode { get; set; } = string.Empty;
        public string ErrorMessage { get; set; } = string.Empty;
        public List<DataAreaEntry> DataAreas { get; set; } = new List<DataAreaEntry>();
        public List<NtfsAutomaticEnsurePreviewEntry> AutomaticEnsurePreview { get; set; } = new List<NtfsAutomaticEnsurePreviewEntry>();
    }

    public class NtfsAutomaticEnsurePreviewEntry
    {
        public string FolderPath { get; set; } = string.Empty;
        public bool WhatIf { get; set; } = true;
        public string Message { get; set; } = string.Empty;
        public List<string> WouldCreateGroups { get; set; } = new List<string>();
        public List<string> WouldReuseGroups { get; set; } = new List<string>();
        public List<string> WouldAddAclEntries { get; set; } = new List<string>();
        public List<string> ExistingAclEntries { get; set; } = new List<string>();
        public List<string> WouldEnsureTraverseGroups { get; set; } = new List<string>();
        public List<string> Warnings { get; set; } = new List<string>();
    }

    public class GetSecurityGroupsOperationResult
    {
        public bool Success { get; set; }
        public string ErrorCode { get; set; } = string.Empty;
        public string ErrorMessage { get; set; } = string.Empty;
        public List<SecurityGroupEntry> SecurityGroups { get; set; } = new List<SecurityGroupEntry>();
    }

    public class NtfsOperationResult
    {
        public bool Success { get; set; }
        public ResultToken ResultToken { get; set; }
    }

    public class AdServiceGroupOperationResult
    {
        public bool Success { get; set; }
        public string ErrorCode { get; set; } = string.Empty;
        public string ErrorMessage { get; set; } = string.Empty;
        public List<Tuple<string, string, string, string>> CreatedGroups { get; set; } = new List<Tuple<string, string, string, string>>();
    }

    public class ExchangeProvisionOperationResult
    {
        public bool Success { get; set; }
        public Guid ObjectGuid { get; set; } = Guid.Empty;
        public List<Tuple<string, string, string, string>> CreatedGroups { get; set; } = new List<Tuple<string, string, string, string>>();
        public string ErrorCode { get; set; } = string.Empty;
        public string ErrorMessage { get; set; } = string.Empty;
    }

    public class CloneTeamOperationResult
    {
        public bool Success { get; set; }
        public Guid CreatedTeamId { get; set; } = Guid.Empty;
        public cMsGraphResultBase Result { get; set; }
        public string ErrorCode { get; set; } = string.Empty;
        public string ErrorMessage { get; set; } = string.Empty;
    }

    public static class LiamWorkflowRuntime
    {
        public static async Task<GetDataAreasOperationResult> GetDataAreasFromProviderAsync(cLiamProviderBase provider, string configurationId = null, bool? simulateConfiguredNtfsPermissionEnsure = null)
        {
            var result = new GetDataAreasOperationResult();
            if (provider == null)
            {
                result.ErrorCode = "WF_GET_DATAAREAS_PROVIDER_NOT_FOUND";
                result.ErrorMessage = "Configured provider is not initialized.";
                return result;
            }

            try
            {
                var dataAreas = await provider.getDataAreasAsync(provider.MaxDepth);
                if (dataAreas == null)
                {
                    SetErrorFromProvider(result, provider, "WF_GET_DATAAREAS_PROVIDER_CALL_FAILED", "Provider returned null while reading data areas.");
                    return result;
                }

                var simulateAutomaticEnsure = simulateConfiguredNtfsPermissionEnsure ?? IsWorkflowWhatIfEnabled(provider);
                if (!await EnsureNtfsPermissionGroupsIfConfiguredAsync(provider, dataAreas, result, simulateAutomaticEnsure))
                    return result;

                result.DataAreas = dataAreas
                    .Select(dataArea => MapDataAreaEntry(dataArea, configurationId))
                    .ToList();
                result.Success = true;
                return result;
            }
            catch (Exception ex)
            {
                LogException(ex);
                result.ErrorCode = "WF_GET_DATAAREAS_EXCEPTION";
                result.ErrorMessage = ex.Message;
                return result;
            }
        }

        public static async Task<GetSecurityGroupsOperationResult> GetSecurityGroupsFromProviderAsync(cLiamProviderBase provider)
        {
            var result = new GetSecurityGroupsOperationResult();
            if (provider == null)
            {
                result.ErrorCode = "WF_GET_SECURITYGROUPS_PROVIDER_NOT_FOUND";
                result.ErrorMessage = "Configured provider is not initialized.";
                return result;
            }

            try
            {
                var securityGroups = await provider.getSecurityGroupsAsync(provider.GroupFilter);
                if (securityGroups == null)
                {
                    SetErrorFromProvider(result, provider, "WF_GET_SECURITYGROUPS_PROVIDER_CALL_FAILED", "Provider returned null while reading security groups.");
                    return result;
                }

                result.SecurityGroups = securityGroups
                    .Select(MapSecurityGroupEntry)
                    .ToList();
                result.Success = true;
                return result;
            }
            catch (Exception ex)
            {
                LogException(ex);
                result.ErrorCode = "WF_GET_SECURITYGROUPS_EXCEPTION";
                result.ErrorMessage = ex.Message;
                return result;
            }
        }

        public static async Task<NtfsOperationResult> CreateDataAreaAsync(
            cLiamProviderBase provider,
            string newFolderPath,
            string parentFolderPath,
            IDictionary<string, string> customTags,
            IEnumerable<string> ownerSids,
            IEnumerable<string> readerSids,
            IEnumerable<string> writerSids)
        {
            var result = new NtfsOperationResult();
            if (!(provider is cLiamProviderNtfs ntfsProvider))
            {
                result.ResultToken = CreateInvalidNtfsResultToken("Configured provider is not NTFS or not initialized.");
                return result;
            }

            var token = await ntfsProvider.CreateDataAreaAsync(
                newFolderPath,
                parentFolderPath,
                customTags,
                NormalizeIdentifierList(ownerSids),
                NormalizeIdentifierList(readerSids),
                NormalizeIdentifierList(writerSids),
                IsWorkflowWhatIfEnabled(provider));
            if (token == null)
                token = CreateInvalidNtfsResultToken(ntfsProvider.GetLastErrorMessage() ?? "Provider returned no result while creating the data area.");
            result.ResultToken = token;
            result.Success = token != null && token.resultErrorId == 0;
            return result;
        }

        public static async Task<NtfsOperationResult> EnsureNtfsPermissionGroupsAsync(
            cLiamProviderBase provider,
            string folderPath,
            IDictionary<string, string> customTags,
            IEnumerable<string> ownerSids,
            IEnumerable<string> readerSids,
            IEnumerable<string> writerSids,
            bool ensureTraverseGroups)
        {
            var result = new NtfsOperationResult();
            if (!(provider is cLiamProviderNtfs ntfsProvider) || string.IsNullOrWhiteSpace(folderPath))
            {
                result.ResultToken = CreateInvalidNtfsResultToken(provider is cLiamProviderNtfs
                    ? "Folder path is missing."
                    : "Configured provider is not NTFS or not initialized.");
                return result;
            }

            var allowSharePathEnsure = IsAdditionalConfigurationEnabled(provider, "AllowManualNtfsPermissionEnsureForShares");
            var token = await ntfsProvider.EnsureMissingPermissionGroupsAsync(
                folderPath,
                customTags,
                NormalizeIdentifierList(ownerSids),
                NormalizeIdentifierList(readerSids),
                NormalizeIdentifierList(writerSids),
                allowSharePathEnsure,
                ensureTraverseGroups,
                IsWorkflowWhatIfEnabled(provider));
            if (token == null)
                token = CreateInvalidNtfsResultToken(ntfsProvider.GetLastErrorMessage() ?? "Provider returned no result while ensuring NTFS permission groups.");
            result.ResultToken = token;
            result.Success = token != null && token.resultErrorId == 0;
            return result;
        }

        public static AdServiceGroupOperationResult CreateAdServiceGroups(
            cLiamProviderBase provider,
            string serviceName,
            string description,
            eLiamAccessRoleScopes scope,
            ADGroupType groupType,
            IEnumerable<string> ownerSids,
            IEnumerable<string> memberSids)
        {
            var result = new AdServiceGroupOperationResult();
            if (!(provider is cLiamProviderAD adProvider))
            {
                result.ErrorCode = "WF_PROVIDER_INVALID";
                result.ErrorMessage = "Configured provider is not Active Directory or not initialized.";
                return result;
            }

            try
            {
                var groups = adProvider.CreateServiceGroups(
                    serviceName,
                    description,
                    scope,
                    groupType,
                    NormalizeIdentifierList(ownerSids),
                    NormalizeIdentifierList(memberSids));
                result.Success = groups != null;
                result.CreatedGroups = groups ?? new List<Tuple<string, string, string, string>>();
                return result;
            }
            catch (Exception ex)
            {
                LogException(ex);
                result.ErrorCode = "WF_ACTIVITY_EXCEPTION";
                result.ErrorMessage = ex.Message;
                return result;
            }
        }

        public static async Task<CloneTeamOperationResult> CloneTeamAsync(
            cLiamProviderBase provider,
            string teamId,
            string name,
            string description,
            int visibility,
            int partsToClone,
            string additionalMembers,
            string additionalOwners)
        {
            var result = new CloneTeamOperationResult();
            if (!(provider is cLiamProviderMsTeams msTeamsProvider))
            {
                result.ErrorCode = "WF_PROVIDER_INVALID";
                result.ErrorMessage = "Configured provider is not MsTeams or not initialized.";
                return result;
            }

            try
            {
                var cloneResult = await msTeamsProvider.cloneTeam(teamId, name, description, visibility, partsToClone, additionalMembers, additionalOwners);
                result.Result = cloneResult;
                result.Success = cloneResult != null;

                if (cloneResult?.Result?.targetResourceId != null)
                {
                    string idString = cloneResult.Result.targetResourceId.ToString();
                    Guid createdTeamId;
                    if (Guid.TryParse(idString, out createdTeamId))
                    {
                        result.CreatedTeamId = createdTeamId;
                    }
                    else
                    {
                        LogEntry($"targetResourceId '{idString}' is not a valid Guid.", LogLevels.Warning);
                    }
                }

                return result;
            }
            catch (Exception ex)
            {
                LogException(ex);
                result.ErrorCode = "WF_ACTIVITY_EXCEPTION";
                result.ErrorMessage = ex.Message;
                return result;
            }
        }

        public static ExchangeProvisionOperationResult CreateDistributionGroup(
            cLiamProviderBase provider,
            string name,
            string alias,
            string displayName,
            string primarySmtpAddress)
        {
            var result = new ExchangeProvisionOperationResult();
            if (!(provider is cLiamProviderExchange exchangeProvider))
            {
                result.ErrorCode = "WF_PROVIDER_INVALID";
                result.ErrorMessage = "Configured provider is not Exchange or not initialized.";
                return result;
            }

            try
            {
                var created = exchangeProvider.exchangeManager.CreateDistributionGroupWithOwnershipGroups(
                    name,
                    alias,
                    displayName,
                    primarySmtpAddress,
                    out string errorCode,
                    out string errorMessage);
                result.ErrorCode = errorCode ?? string.Empty;
                result.ErrorMessage = errorMessage ?? string.Empty;

                if (created != null)
                {
                    result.Success = true;
                    result.ObjectGuid = created.Item1;
                    result.CreatedGroups = created.Item2 ?? new List<Tuple<string, string, string, string>>();
                }

                return result;
            }
            catch (Exception ex)
            {
                LogException(ex);
                result.ErrorCode = "WF_ACTIVITY_EXCEPTION";
                result.ErrorMessage = ex.Message;
                return result;
            }
        }

        public static ExchangeProvisionOperationResult CreateSharedMailbox(
            cLiamProviderBase provider,
            string name,
            string alias,
            string displayName,
            string primarySmtpAddress)
        {
            var result = new ExchangeProvisionOperationResult();
            if (!(provider is cLiamProviderExchange exchangeProvider))
            {
                result.ErrorCode = "WF_PROVIDER_INVALID";
                result.ErrorMessage = "Configured provider is not Exchange or not initialized.";
                return result;
            }

            try
            {
                var created = exchangeProvider.exchangeManager.CreateSharedMailboxWithOwnershipGroups(
                    name,
                    alias,
                    displayName,
                    primarySmtpAddress,
                    out string errorCode,
                    out string errorMessage);
                result.ErrorCode = errorCode ?? string.Empty;
                result.ErrorMessage = errorMessage ?? string.Empty;

                if (created != null)
                {
                    result.Success = true;
                    result.ObjectGuid = created.Item1;
                    result.CreatedGroups = created.Item2 ?? new List<Tuple<string, string, string, string>>();
                }

                return result;
            }
            catch (Exception ex)
            {
                LogException(ex);
                result.ErrorCode = "WF_ACTIVITY_EXCEPTION";
                result.ErrorMessage = ex.Message;
                return result;
            }
        }

        private static ResultToken CreateInvalidNtfsResultToken(string message)
        {
            return new ResultToken("LiamWorkflowRuntime")
            {
                resultErrorId = 1,
                resultMessage = message ?? string.Empty
            };
        }

        private static IEnumerable<string> NormalizeIdentifierList(IEnumerable<string> identifiers)
        {
            if (identifiers == null)
                return Enumerable.Empty<string>();

            return identifiers
                .Select(i => i?.Trim())
                .Where(i => !string.IsNullOrWhiteSpace(i))
                .Distinct(StringComparer.OrdinalIgnoreCase)
                .ToList();
        }

        private static async Task<bool> EnsureNtfsPermissionGroupsIfConfiguredAsync(cLiamProviderBase provider, List<cLiamDataAreaBase> dataAreas, GetDataAreasOperationResult result, bool simulateOnly)
        {
            if (!(provider is cLiamProviderNtfs ntfsProvider))
                return true;

            var allowFolderEnsure = IsAdditionalConfigurationEnabled(provider, "EnsureNtfsPermissionGroups");
            var allowSharePathEnsure = IsAdditionalConfigurationEnabled(provider, "EnsureNtfsPermissionGroupsForShares");
            if (!allowFolderEnsure && !allowSharePathEnsure)
                return true;

            foreach (var ntfsArea in dataAreas
                .Where(dataArea =>
                    allowFolderEnsure && dataArea is cLiamNtfsFolder
                    || allowSharePathEnsure && dataArea is cLiamNtfsShare)
                .Cast<cLiamNtfsPermissionDataAreaBase>())
            {
                var folderPath = ntfsArea.TechnicalName;
                if (string.IsNullOrWhiteSpace(folderPath))
                    continue;

                if (!Directory.Exists(folderPath))
                {
                    LogEntry($"Skipping automatic NTFS permission group ensure for '{folderPath}' because the directory does not exist.", LogLevels.Warning);
                    continue;
                }

                var ensureResult = await ntfsProvider.EnsureMissingPermissionGroupsAsync(
                    folderPath,
                    null,
                    null,
                    null,
                    null,
                    allowSharePathEnsure,
                    ntfsArea is cLiamNtfsFolder || ntfsArea is cLiamNtfsShare,
                    simulateOnly);
                if (ensureResult == null)
                {
                    result.ErrorCode = "WF_GET_DATAAREAS_ENSURE_NTFS_GROUPS_FAILED";
                    result.ErrorMessage = $"Automatic NTFS permission group ensure failed for '{folderPath}' because the provider returned no result.";
                    return false;
                }

                if (ensureResult.resultErrorId != 0)
                {
                    result.ErrorCode = "WF_GET_DATAAREAS_ENSURE_NTFS_GROUPS_FAILED";
                    result.ErrorMessage = $"Automatic NTFS permission group ensure failed for '{folderPath}': {ensureResult.resultMessage}";
                    return false;
                }

                if (simulateOnly)
                {
                    LogAutomaticNtfsEnsurePreviewDebug(folderPath, ensureResult);
                    result.AutomaticEnsurePreview.Add(MapAutomaticEnsurePreview(folderPath, ensureResult));
                    continue;
                }

                LogAutomaticNtfsEnsureDebug(folderPath, ensureResult);
                await ntfsArea.ResolvePermissionGroupsAsync(folderPath);
            }

            return true;
        }

        private static NtfsAutomaticEnsurePreviewEntry MapAutomaticEnsurePreview(string folderPath, ResultToken ensureResult)
        {
            return new NtfsAutomaticEnsurePreviewEntry
            {
                FolderPath = folderPath ?? string.Empty,
                WhatIf = true,
                Message = ensureResult?.resultMessage ?? string.Empty,
                WouldCreateGroups = ensureResult?.createdGroups?.ToList() ?? new List<string>(),
                WouldReuseGroups = ensureResult?.reusedGroups?.ToList() ?? new List<string>(),
                WouldAddAclEntries = ensureResult?.addedAclEntries?.ToList() ?? new List<string>(),
                ExistingAclEntries = ensureResult?.skippedAclEntries?.ToList() ?? new List<string>(),
                WouldEnsureTraverseGroups = ensureResult?.ensuredTraverseGroups?.ToList() ?? new List<string>(),
                Warnings = ensureResult?.warnings?.ToList() ?? new List<string>()
            };
        }

        private static void LogAutomaticNtfsEnsurePreviewDebug(string folderPath, ResultToken ensureResult)
        {
            if (ensureResult == null)
                return;

            LogEntry(
                $"Automatic NTFS permission group ensure preview finished for '{folderPath}'. " +
                $"WouldCreateGroups={ensureResult.createdGroups.Count}, " +
                $"WouldReuseGroups={ensureResult.reusedGroups.Count}, " +
                $"WouldAddAcls={ensureResult.addedAclEntries.Count}, " +
                $"ExistingAcls={ensureResult.skippedAclEntries.Count}, " +
                $"WouldEnsureTraverseGroups={ensureResult.ensuredTraverseGroups.Count}, " +
                $"Warnings={ensureResult.warnings.Count}, " +
                $"ResultMessage='{ensureResult.resultMessage ?? string.Empty}'",
                LogLevels.Debug);
        }

        private static void LogAutomaticNtfsEnsureDebug(string folderPath, ResultToken ensureResult)
        {
            if (ensureResult == null)
                return;

            LogEntry(
                $"Automatic NTFS permission group ensure finished for '{folderPath}'. " +
                $"CreatedGroups={ensureResult.createdGroups.Count}, " +
                $"ReusedGroups={ensureResult.reusedGroups.Count}, " +
                $"AddedAcls={ensureResult.addedAclEntries.Count}, " +
                $"SkippedAcls={ensureResult.skippedAclEntries.Count}, " +
                $"TraverseGroups={ensureResult.ensuredTraverseGroups.Count}, " +
                $"Warnings={ensureResult.warnings.Count}, " +
                $"ResultMessage='{ensureResult.resultMessage ?? string.Empty}'",
                LogLevels.Debug);

            if (ensureResult.createdGroups.Count > 0)
            {
                LogEntry(
                    $"Automatic NTFS permission group ensure detected missing AD groups for '{folderPath}' and created them: {string.Join(", ", ensureResult.createdGroups)}",
                    LogLevels.Debug);
            }

            if (ensureResult.reusedGroups.Count > 0)
            {
                LogEntry(
                    $"Automatic NTFS permission group ensure reused existing AD groups for '{folderPath}': {string.Join(", ", ensureResult.reusedGroups)}",
                    LogLevels.Debug);
            }

            if (ensureResult.addedAclEntries.Count > 0)
            {
                LogEntry(
                    $"Automatic NTFS permission group ensure added missing ACL entries for '{folderPath}': {string.Join(", ", ensureResult.addedAclEntries)}",
                    LogLevels.Debug);
            }

            if (ensureResult.skippedAclEntries.Count > 0)
            {
                LogEntry(
                    $"Automatic NTFS permission group ensure kept existing ACL entries for '{folderPath}': {string.Join(", ", ensureResult.skippedAclEntries)}",
                    LogLevels.Debug);
            }

            if (ensureResult.ensuredTraverseGroups.Count > 0)
            {
                LogEntry(
                    $"Automatic NTFS permission group ensure touched traverse groups for '{folderPath}': {string.Join(", ", ensureResult.ensuredTraverseGroups)}",
                    LogLevels.Debug);
            }

            if (ensureResult.warnings.Count > 0)
            {
                LogEntry(
                    $"Automatic NTFS permission group ensure produced warnings for '{folderPath}': {string.Join(" | ", ensureResult.warnings)}",
                    LogLevels.Debug);
            }
        }

        private static bool IsAdditionalConfigurationEnabled(cLiamProviderBase provider, string key)
        {
            if (provider?.AdditionalConfiguration == null || string.IsNullOrWhiteSpace(key))
                return false;

            if (!provider.AdditionalConfiguration.TryGetValue(key, out var rawValue) || string.IsNullOrWhiteSpace(rawValue))
                return false;

            return rawValue.Equals("true", StringComparison.OrdinalIgnoreCase)
                || rawValue.Equals("1", StringComparison.OrdinalIgnoreCase)
                || rawValue.Equals("yes", StringComparison.OrdinalIgnoreCase);
        }

        private static bool IsWorkflowWhatIfEnabled(cLiamProviderBase provider)
        {
            return IsAdditionalConfigurationEnabled(provider, "WhatIf");
        }

        private static void SetErrorFromProvider(GetDataAreasOperationResult result, cLiamProviderBase provider, string fallbackCode, string fallbackMessage)
        {
            var error = ExtractProviderError(provider, fallbackCode, fallbackMessage);
            result.ErrorCode = error.Item1;
            result.ErrorMessage = error.Item2;
        }

        private static void SetErrorFromProvider(GetSecurityGroupsOperationResult result, cLiamProviderBase provider, string fallbackCode, string fallbackMessage)
        {
            var error = ExtractProviderError(provider, fallbackCode, fallbackMessage);
            result.ErrorCode = error.Item1;
            result.ErrorMessage = error.Item2;
        }

        private static Tuple<string, string> ExtractProviderError(cLiamProviderBase provider, string fallbackCode, string fallbackMessage)
        {
            if (provider is cLiamProviderExchange exchangeProvider)
            {
                var code = exchangeProvider.GetLastErrorCode();
                var message = exchangeProvider.GetLastErrorMessage();
                if (!string.IsNullOrWhiteSpace(code) || !string.IsNullOrWhiteSpace(message))
                {
                    return Tuple.Create(
                        string.IsNullOrWhiteSpace(code) ? fallbackCode : code,
                        string.IsNullOrWhiteSpace(message) ? fallbackMessage : message);
                }
            }

            var providerMessage = provider?.GetLastErrorMessage();
            return Tuple.Create(
                fallbackCode,
                string.IsNullOrWhiteSpace(providerMessage) ? fallbackMessage : providerMessage);
        }

        private static DataAreaEntry MapDataAreaEntry(cLiamDataAreaBase dataArea, string configurationId)
        {
            var ntfsPermissionArea = dataArea as cLiamNtfsPermissionDataAreaBase;
            var ntfsFolder = dataArea as cLiamNtfsFolder;
            var adGroup = dataArea as cLiamAdGroupAsDataArea;
            var exchangeMailbox = dataArea as cLiamExchangeSharedMailbox;
            var exchangeDistribution = dataArea as cLiamExchangeDistributionGroup;

            var owner = exchangeMailbox?.OwnerGroupIdentifier
                        ?? exchangeDistribution?.OwnerGroupIdentifier
                        ?? adGroup?.ManagedBySID
                        ?? ntfsPermissionArea?.OwnerGroupIdentifier
                        ?? string.Empty;

            var write = exchangeMailbox != null
                ? exchangeMailbox.FullAccessGroupSid
                : exchangeDistribution != null
                    ? exchangeDistribution.MemberGroupSid
                    : adGroup?.UID
                      ?? ntfsPermissionArea?.WriteGroupIdentifier
                      ?? string.Empty;

            var read = exchangeMailbox != null
                ? exchangeMailbox.SendAsGroupSid
                : ntfsPermissionArea?.ReadGroupIdentifier
                  ?? string.Empty;

            var traverse = ntfsPermissionArea?.TraverseGroupIdentifier ?? string.Empty;
            var created = ntfsPermissionArea?.CreatedDate ?? DateTime.MinValue.ToString("o");
            var description = adGroup?.Description ?? string.Empty;

            return new DataAreaEntry
            {
                DisplayName = dataArea.DisplayName ?? string.Empty,
                UID = dataArea.UID ?? string.Empty,
                TechnicalName = dataArea.TechnicalName ?? string.Empty,
                Description = description,
                TargetType = ((int)dataArea.Provider.ProviderType).ToString(),
                ParentUID = dataArea.ParentUID ?? string.Empty,
                Level = dataArea.Level.ToString(),
                Owner = owner,
                Write = write,
                Read = read,
                Traverse = traverse,
                CreatedDate = created,
                ConfigurationId = configurationId ?? string.Empty,
                BaseFolder = ntfsFolder?.Share?.TechnicalName ?? dataArea.Provider?.RootPath ?? string.Empty,
                UniqueId = dataArea.UID ?? string.Empty,
                DataAreaType = dataArea.DataType.ToString(),
                DataAreaTypeId = (int)dataArea.DataType
            };
        }

        private static SecurityGroupEntry MapSecurityGroupEntry(cLiamDataAreaBase securityGroup)
        {
            var entry = new SecurityGroupEntry
            {
                DisplayName = securityGroup.TechnicalName,
                TechnicalName = securityGroup.UID,
                TargetType = ((int)securityGroup.Provider.ProviderType).ToString()
            };

            switch (securityGroup)
            {
                case cLiamAdGroup adGroup:
                    entry.UID = adGroup.dn;
                    entry.Scope = adGroup.scope;
                    break;
                case cLiamAdGroup2 adGroup2:
                    entry.UID = adGroup2.dn;
                    entry.Scope = adGroup2.scope;
                    break;
                case cLiamExchangeSecurityGroup exchangeGroup:
                    entry.UID = exchangeGroup.dn;
                    break;
            }

            return entry;
        }
    }
}
