using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LeafWeb.Core.Charter;
using LeafWeb.Core.Entities;
using LeafWeb.Core.Parsers;
using LeafWeb.Core.Utility;
using NUnit.Framework;

namespace LeafWeb.Core.Tests.Charter
{
    [TestFixture]
    public class ChartInputTests
    {
        private const string ContentDirectory = @"C:\temp\leafgascomparison\";

        private struct Stats
        {
            public FileInfo FileInfo;
            public int Lines;
            public int LeafGasComparisonCount;
            public int CurveDataCount;
            public string FailureLocation;
            public Exception Exception;
        }

        [Test, Explicit]
        public void LeafGasComparison_Stats()
        {
            var leafgasComparisonFiles = Directory.GetFiles(ContentDirectory);
            var stats = new List<Stats>();
            foreach (var file in leafgasComparisonFiles.OrderBy(f => f))//.Take(10))
            {
                //var fileInfo = FileUtility.GetContentFile(ContentDirectory, file);
                var fileInfo = new FileInfo(file);
                stats.Add(GetStats(fileInfo));
            }

            Console.WriteLine("Filename\tLine Count\tLeafGasComparisonDataCount\tCurveDataCount\tStatus");
            foreach (var stat in stats)
            {
                string output = stat.FileInfo.Name;
                output += $"\t{stat.Lines}";
                output += $"\t{stat.LeafGasComparisonCount}";
                output += $"\t{stat.CurveDataCount}";
                if (string.IsNullOrEmpty(stat.FailureLocation))
                {
                    output += "\tsuccess";
                }
                else
                {
                    output += $"\tfailed at {stat.FailureLocation}: {stat.Exception.Message}";
                }

                Console.WriteLine(output);
            }

            foreach (var stat in stats)
            {
                if (string.IsNullOrEmpty(stat.FailureLocation))
                {
                    if (stat.CurveDataCount > 0)
                    {
                        File.Copy(stat.FileInfo.FullName, @"C:\temp\leafgascomparison\Good\" + stat.FileInfo.Name);
                    }
                    else
                    {
                        File.Copy(stat.FileInfo.FullName, @"C:\temp\leafgascomparison\NoCurveData\" + stat.FileInfo.Name);
                    }
                }
                else
                {
                    if (stat.FailureLocation == "LeafGasComparisonParser")
                    {
                        File.Copy(stat.FileInfo.FullName, @"C:\temp\leafgascomparison\CannotParse\" + stat.FileInfo.Name);
                    }
                    else if (stat.FailureLocation == "CurveDataConverter")
                    {
                        File.Copy(stat.FileInfo.FullName, @"C:\temp\leafgascomparison\PartialCurveData\" + stat.FileInfo.Name);
                    }

                }
            }
        }

        private Stats GetStats(FileInfo fileInfo)
        {
            var stats = new Stats {FileInfo = fileInfo};

            stats.Lines = File.ReadLines(fileInfo.FullName).Count();

            LeafGasComparison[] leafGasComparisons;

            try
            {
                using (var parser = new LeafGasComparisonParser(fileInfo))
                    leafGasComparisons = parser.Parse();
            }
            catch (Exception e)
            {
                stats.FailureLocation = "LeafGasComparisonParser";
                stats.Exception = e;
                return stats;
            }

            stats.LeafGasComparisonCount = leafGasComparisons.Length;

            IEnumerable<CurveData> curves;
            try
            {
                curves = CurveDataConverter.Convert(leafGasComparisons);
                stats.CurveDataCount = curves.Count();
            }
            catch (Exception e)
            {
                stats.FailureLocation = "CurveDataConverter";
                stats.Exception = e;
                return stats;
            }

            return stats;
        }
    }
}
