using log4net;
using log4net.Repository.Hierarchy;
using skyscraper5.Docsis.MacManagement;
using skyscraper5.Skyscraper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace skyscraper8.Skyscraper
{
    internal class TsRotationToCsv
    {
        public DirectoryInfo SourceDir { get; set; }
        public FileInfo DestinationCsv { get; set; }

        private List<FileInfo> files;
        private ILog logger;
        public void Run()
        {
            logger = LogManager.GetLogger(typeof(TsRotationToCsv));
            files = new List<FileInfo>();
            ScrapeDirectory(SourceDir);
            files.Sort(new FileInfoComparerByDate(logger));
            DumpCsv();
        }

        private void DumpCsv()
        {
            StreamWriter sw = new StreamWriter(DestinationCsv.FullName);
            foreach (FileInfo file in files)
            {
                sw.WriteLine(String.Format("\"{0}\";{1};{2}", file.FullName, file.Length, file.LastWriteTime));
            }
            sw.Flush();
            sw.Close();
        }

        private void ScrapeDirectory(DirectoryInfo di)
        {
            try
            {
                foreach (FileSystemInfo fsi in di.GetFileSystemInfos())
                {
                    switch (fsi)
                    {
                        case FileInfo fi:
                            if (fi.Extension.ToLowerInvariant().Equals(".ts"))
                            {
                                files.Add(fi);
                                if (files.Count % 100 == 0)
                                    logger.InfoFormat("Listed {0} files.", files.Count);
                            }
                            break;
                        case DirectoryInfo subdirectory:
                            ScrapeDirectory(subdirectory);
                            break;
                        default:
                            throw new NotImplementedException(di.GetType().Name);
                    }
                }
            }
            catch (Exception e)
            {
                logger.WarnFormat(e.Message);
            }
        }

        private class FileInfoComparerByDate : Comparer<FileInfo>
        {
            private ILog logger;
            private int ups, downs, stands;

            public FileInfoComparerByDate(ILog logger)
            {
                this.logger = logger;
            }

            public override int Compare(FileInfo? x, FileInfo? y)
            {
                long xTime = x.LastWriteTime.ToUnixTime();
                long yTime = y.LastWriteTime.ToUnixTime();

                int ops;
                int v = xTime.CompareTo(yTime);
                switch(v)
                {
                    case -1:
                        ups++;
                        ops = ups;
                        break;
                    case 0:
                        stands++;
                        ops = stands;
                        break;
                    case 1:
                        downs++;
                        ops = downs;
                        break;
                    default:
                        throw new NotImplementedException(v.ToString());
                }
                if (ops % 1000 == 0)
                {
                    logger.InfoFormat("Sort progress: {0} up, {1} down, {2} stand.", ups, downs, stands);
                }
                return v;
            }
        }
    }
}
