﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;

namespace OfficeOpenXml.FormulaParsing.Logging
{
    internal class TextFileLogger : IFormulaParserLogger
    {
        private StreamWriter _sw;
        private const string Separator = "=================================";
        private int _count;
        private DateTime _startTime = DateTime.Now;
        private Dictionary<string, int> _funcs = new Dictionary<string, int>();
        private Dictionary<string, long> _funcPerformance = new Dictionary<string, long>();
        internal TextFileLogger(FileInfo fileInfo)
        {
            _sw = new StreamWriter(fileInfo.FullName);
        }

        private void WriteSeparatorAndTimeStamp()
        {
            _sw.WriteLine(Separator);
            _sw.WriteLine("Timestamp: {0}", DateTime.Now);
            _sw.WriteLine();
        }

        private void WriteAddressInfo(ParsingContext context)
        {
            if (context.Scopes.Current != null && context.Scopes.Current.Address != null)
            {
                _sw.WriteLine("Worksheet: {0}", context.Scopes.Current.Address.Worksheet ?? "<not specified>");
                _sw.WriteLine("Address: {0}", context.Scopes.Current.Address.Address ?? "<not available>");
            }
        }

        public void Log(ParsingContext context, Exception ex)
        {
            WriteSeparatorAndTimeStamp();
            WriteAddressInfo(context);
            _sw.WriteLine(ex);
            _sw.WriteLine();
        }

        public void Log(ParsingContext context, string message)
        {
            WriteSeparatorAndTimeStamp();
            WriteAddressInfo(context);
            _sw.WriteLine(message);
            _sw.WriteLine();
        }

        public void Log(string message)
        {
            WriteSeparatorAndTimeStamp();
            _sw.WriteLine(message);
            _sw.WriteLine();
        }

        public void LogCellCounted()
        {
            _count++;
            if (_count%500 == 0)
            {
                _sw.WriteLine(Separator);
                var timeEllapsed = DateTime.Now.Subtract(_startTime);
                _sw.WriteLine("{0} cells parsed, time {1} seconds", _count, timeEllapsed.TotalSeconds);

                var funcs = _funcs.Keys.OrderByDescending(x => _funcs[x]).ToList();
                foreach (var func in funcs)
                {
                    _sw.Write(func + "  - " + _funcs[func]);
                    if (_funcPerformance.ContainsKey(func))
                    {
                        _sw.Write(" - avg: " + _funcPerformance[func]/_funcs[func] + " milliseconds");
                    }
                    _sw.WriteLine();
                }
                _sw.WriteLine();
                _funcs.Clear();

            }
        }

        public void LogFunction(string func)
        {
            if (!_funcs.ContainsKey(func))
            {
                _funcs.Add(func, 0);
            }
            _funcs[func]++;
        }

        public void LogFunction(string func, long milliseconds)
        {
            if (!_funcPerformance.ContainsKey(func))
            {
                _funcPerformance[func] = 0;
            }
            _funcPerformance[func] += milliseconds;
        }

        public void Dispose()
        {
            _sw.Close(); 
            _sw.Dispose();
        }
    }
}
