using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using DDUtilityApp.DATA;
using DDUtilityApp.LOGPARSER.DATA;
using DDUtilityApp.SECS;
using JWH;
using JWH.CONTROL;

namespace DDUtilityApp.LOGPARSER.PARSER
{

    public abstract class LogParser
    {

        public delegate object Parser(StreamReader reader, ref string startLine);

        #region [ Properties ] ------------------------------------------------

        public string Text { get; set; } = "[EverOne] Log Viewer";

        public string ServerName { get; set; } = string.Empty;

        public string EquipmentID { get; set; } = string.Empty;

        public string ModelID { get; set; }

        public SECSDefine SECSDefine { get; set; } = null;

        public List<string> Files { get; set; } = new List<string>();

        /// <summary>
        /// 로그서버 접속정보
        /// </summary>
        public Account Account { get; set; } = null;

        public StandardCollection StandardCollection { get; set; } = new StandardCollection();

        public StringBuilder LogString { get; set; } = new StringBuilder();

        protected int LogDTimeStart { get; set; } = 0;

        protected string LogDTime { get; set; } = "yyyy-MM-dd HH:mm:ss.fff";

        protected int LineNumber { get; set; } = 0;

        protected string LastReadLine { get; set; } = string.Empty;

        protected long StreamPosition { get; set; } = 0;

        #endregion

        #region [ LogParser ] -------------------------------------------------

        public LogParser()
        {
        }

        public LogParser(params string[] files) : this()
        {
            //this.Childs.AddRange(from file in files orderby file select file);
            this.Files.AddRange(files);
        }

        protected void Initilize()
        {
            this.StandardCollection.Clear();
            this.LogString.Clear();
            this.LineNumber = 0;
        }

        #endregion

        #region [ Method ] ----------------------------------------------------

        public virtual void SetGridHeader(GridViewEx grid)
        {
            grid.AddColumn("DateTime");
            grid.AddColumn("Level");
            grid.AddColumn("Server");
            grid.AddColumn("Service");
            grid.AddColumn("Type");
            grid.AddColumn("MessageName");
            grid.AddColumn("Return");
            grid.AddColumn("Value");
            grid.AddColumn("LotID");
            grid.AddColumn("CarrierID");
            grid.AddColumn("EquipmentID");
            grid.AddColumn("PortID");
            grid.AddColumn("SystemByte");
            grid.AddColumn("ModuleID");
            grid.AddColumn("HostPanelID");
            grid.AddColumn("PanelID");
            grid.AddColumn("PanelQty");
            grid.AddColumn("TID");
            grid.AddColumn("Column1");
            grid.AddColumn("Column2");
            grid.AddColumn("Column3");
            grid.AddColumn("Column4");
            grid.AddColumn("Column5");
        }

        public virtual void SaveGridHeader(GridViewEx grid)
        {
        }

        public virtual LogFile[] FileSelector(FrmLogParser sender, params LogFile[] args)
        {
            string directoryName = string.Empty;
            string fileName = string.Empty;
            if (args != null && args.Length > 0)
            {
                directoryName = args[0].DirectoryName;
                fileName = args[0].FileName;
            }

            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Multiselect = true;
            dlg.InitialDirectory = directoryName;
            dlg.FileName = fileName;

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                List<LogFile> lstFiles = new List<LogFile>();
                foreach (string name in dlg.FileNames)
                {
                    FileInfo fileInfo = new FileInfo(name);
                    lstFiles.Add(fileInfo.ToClass<LogFile>());
                }

                return lstFiles.ToArray();
            }

            return null;
        }

        public abstract bool Parsing();

        public bool Parsing(params string[] files)
        {
            this.Files.Clear();
            this.Files.AddRange(files);
            
            return this.Parsing();
        }

        protected string GetReadLine(StreamReader reader, bool isWrite = true)
        {
            try
            {
                this.StreamPosition = reader.BaseStream.Position;
                string strLine = reader.ReadLine();

                if (isWrite)
                {
                    this.LineNumber++;
                    this.LogString.AppendLine($"{this.LineNumber.ToString("000000")}: {strLine}");
                    //XLogger.Instance.Debug($"{this.LineNumber.ToString("000000")}: {strLine}");
                }

                return strLine;
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
                return string.Empty;
            }
        }

        protected void LogString_Append(string strLine)
        {
            foreach (string value in strLine.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
            {
                this.LineNumber++;
                this.LogString.AppendLine($"{this.LineNumber.ToString("000000")}: {value}");
                //XLogger.Instance.Debug($"{this.LineNumber.ToString("000000")}: {value}");
            }
        }

        #endregion

    }

}
