using System;
using System.IO;
using System.IO.Abstractions;
using System.Linq;

namespace Quadarax.Foundation.Core.IO.Extensions
{
    public static class DirectoryInfoExt
    {
        public static Stream CreateFile(this IDirectoryInfo dirInfo, string fileNameWithExtension, bool forceOverwrite = false)
        {
            if (dirInfo == null)
                throw new ArgumentNullException(nameof(dirInfo));
            if (string.IsNullOrEmpty(fileNameWithExtension))
                throw new ArgumentNullException(nameof(fileNameWithExtension));

            if (forceOverwrite)
            {

                var fileInfo = dirInfo.GetFiles(fileNameWithExtension).FirstOrDefault();
                fileInfo?.Delete();
            }

            var fullFileName = dirInfo.FileSystem.Path.Combine(dirInfo.FullName, fileNameWithExtension);
            return dirInfo.FileSystem.File.OpenWrite(fullFileName);
        }

        public static bool DeleteFile(this IDirectoryInfo dirInfo, string fileNameWithExtension)
        {
            if (dirInfo == null)
                throw new ArgumentNullException(nameof(dirInfo));
            if (string.IsNullOrEmpty(fileNameWithExtension))
                throw new ArgumentNullException(nameof(fileNameWithExtension));


            var fileInfo = dirInfo.GetFiles(fileNameWithExtension).FirstOrDefault();
            var result = fileInfo != null;
            fileInfo?.Delete();
            return result;
        }

        public static string GetFullFileName(this IDirectoryInfo dirInfo, string fileNameWithExtension)
        {
            if (dirInfo == null)
                throw new ArgumentNullException(nameof(dirInfo));
            if (string.IsNullOrEmpty(fileNameWithExtension))
                throw new ArgumentNullException(nameof(fileNameWithExtension));

            return dirInfo.FileSystem.Path.Combine(dirInfo.FullName, fileNameWithExtension);
        }

        public static bool ExistsFile(this IDirectoryInfo dirInfo, string fileNameWithExtension)
        {
            if (dirInfo == null)
                throw new ArgumentNullException(nameof(dirInfo));
            if (string.IsNullOrEmpty(fileNameWithExtension))
                throw new ArgumentNullException(nameof(fileNameWithExtension));

            return dirInfo.GetFiles(fileNameWithExtension).Any();
        }

        public static bool Exists(this IDirectoryInfo dirInfo, string subDirectoryName)
        {
            if (dirInfo == null)
                throw new ArgumentNullException(nameof(dirInfo));
            if (string.IsNullOrEmpty(subDirectoryName))
                throw new ArgumentNullException(nameof(subDirectoryName));

            return dirInfo.Exists && dirInfo.GetDirectories(subDirectoryName, SearchOption.TopDirectoryOnly).Any();
        }

        public static IDirectoryInfo? GetDirectory(this IDirectoryInfo dirInfo, string subDirectoryName)
        {
            if (dirInfo == null)
                throw new ArgumentNullException(nameof(dirInfo));
            if (string.IsNullOrEmpty(subDirectoryName))
                throw new ArgumentNullException(nameof(subDirectoryName));

            return dirInfo.GetDirectories(subDirectoryName, SearchOption.TopDirectoryOnly).FirstOrDefault();
        }

    }
}
