using Microsoft.Extensions.Logging;

namespace File_Folder_Helper.Helpers;

internal static class HelperDeleteEmptyDirectories
{

    private static void DeleteOldLogFilesAndDeleteEmptyDirectories(long? ticks, string? searchPattern, string checkDirectory, List<string> deletedDirectories)
    {
        string[] files;
        FileInfo fileInfo;
        string[] directories = Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly);
        if (ticks is not null && !string.IsNullOrEmpty(searchPattern))
        {
            files = Directory.GetFiles(checkDirectory, searchPattern, SearchOption.TopDirectoryOnly);
            foreach (string file in files)
            {
                fileInfo = new(file);
                if (fileInfo.LastWriteTime.Ticks > ticks.Value)
                    continue;
                try
                { File.Delete(file); }
                catch (IOException) { }
            }
        }
        if (directories.Length > 0)
            files = [];
        else
            files = Directory.GetFiles(checkDirectory, "*", SearchOption.TopDirectoryOnly);
        if (directories.Length == 0 && files.Length == 0)
        {
            try
            { Directory.Delete(checkDirectory); }
            catch (UnauthorizedAccessException)
            {
                new DirectoryInfo(checkDirectory).Attributes = FileAttributes.Normal;
                Directory.Delete(checkDirectory);
            }
            deletedDirectories.Add(checkDirectory);
        }
        else
        {
            List<string> check = [];
            foreach (string directory in directories)
            {
                DeleteOldLogFilesAndDeleteEmptyDirectories(ticks, searchPattern, directory, check);
                deletedDirectories.AddRange(check);
                if (check.Count > 0 && Directory.Exists(directory))
                    DeleteOldLogFilesAndDeleteEmptyDirectories(ticks, searchPattern, directory, deletedDirectories);
            }
        }
    }

    private static void DeleteOldLogFilesAndDeleteEmptyDirectories(ILogger<Worker> logger, long? ticks, string? searchPattern, string rootDirectory)
    {
        List<string> check = [];
        List<string> directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly).ToList();
        directories.Add(rootDirectory);
        foreach (string directory in directories)
        {
            logger.LogInformation("{directoryName}", Path.GetFileName(directory));
            for (int i = 1; i < 50; i++)
            {
                if (!Directory.Exists(directory))
                    break;
                check.Clear();
                DeleteOldLogFilesAndDeleteEmptyDirectories(ticks, searchPattern, directory, check);
                if (check.Count == 0)
                    break;
            }
        }
    }

    internal static void DeleteEmptyDirectories(ILogger<Worker> logger, string rootDirectory)
    {
        long? ticks = null;
        string? searchPattern = null;
        DeleteOldLogFilesAndDeleteEmptyDirectories(logger, ticks, searchPattern, rootDirectory);
    }

    internal static void DeleteOldLogFilesAndDeleteEmptyDirectories(ILogger<Worker> logger, string rootDirectory)
    {
        long ticks = DateTime.Now.AddHours(-84).Ticks;
        DeleteOldLogFilesAndDeleteEmptyDirectories(logger, ticks, "*.log*", rootDirectory);
    }

    internal static void EverythingDeleteRecursive(ILogger<Worker> logger, string rootDirectory)
    {
        if (!Path.GetFileName(rootDirectory).StartsWith("_ EverythingDeleteRecursive "))
            logger.LogInformation("Directory name must start with {<rootDirectory>}", rootDirectory);
        else
        {
            string[] directories2;
            string[] directories3;
            string[] directories4;
            string[] directories5;
            bool errorHappened = false;
            string[] directories1 = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly);
            foreach (string directory1 in directories1)
            {
                directories2 = Directory.GetDirectories(directory1, "*", SearchOption.TopDirectoryOnly);
                foreach (string directory2 in directories2)
                {
                    directories3 = Directory.GetDirectories(directory2, "*", SearchOption.TopDirectoryOnly);
                    foreach (string directory3 in directories3)
                    {
                        directories4 = Directory.GetDirectories(directory3, "*", SearchOption.TopDirectoryOnly);
                        foreach (string directory4 in directories4)
                        {
                            directories5 = Directory.GetDirectories(directory4, "*", SearchOption.TopDirectoryOnly);
                            foreach (string directory5 in directories5)
                            {
                                try
                                {
                                    logger.LogInformation("{directoryName}", Path.GetFileName(directory5));
                                    Directory.Delete(directory5, recursive: true);
                                }
                                catch (Exception)
                                { errorHappened = true; }
                            }
                            if (!errorHappened)
                            {
                                try
                                {
                                    logger.LogInformation("{directoryName}", Path.GetFileName(directory4));
                                    Directory.Delete(directory4, recursive: true);
                                }
                                catch (Exception)
                                { errorHappened = true; }
                            }
                        }
                        if (!errorHappened)
                        {
                            try
                            {
                                logger.LogInformation("{directoryName}", Path.GetFileName(directory3));
                                Directory.Delete(directory3, recursive: true);
                            }
                            catch (Exception)
                            { errorHappened = true; }
                        }
                    }
                    if (!errorHappened)
                    {
                        try
                        {
                            logger.LogInformation("{directoryName}", Path.GetFileName(directory2));
                            Directory.Delete(directory2, recursive: true);
                        }
                        catch (Exception)
                        { errorHappened = true; }
                    }
                }
                if (!errorHappened)
                {
                    try
                    {
                        logger.LogInformation("{directoryName}", Path.GetFileName(directory1));
                        Directory.Delete(directory1, recursive: true);
                    }
                    catch (Exception)
                    { errorHappened = true; }
                }
            }
            if (!errorHappened)
            {
                try
                {
                    logger.LogInformation("{directoryName}", Path.GetFileName(rootDirectory));
                    Directory.Delete(rootDirectory, recursive: true);
                }
                catch (Exception)
                { errorHappened = true; }
            }
            if (!errorHappened)
                logger.LogInformation("Finished");
            else
                logger.LogInformation("Error(s) occurred");
        }
    }

}