using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Project.Manager
{
    public class DatabaseManagerCount
    {
        /// <summary>
        /// 파일검색방법
        /// </summary>
        public enum eFileSearchMode
        {
            Normal,
            Project,
            Model,
            MCCode,
            Barcode,
            All,
        }

        public enum eStripSearchResult
        {
            None,
            OK,
            NG,
        }

        /// <summary>
        /// 최종파일
        /// </summary>
        private String LastFileName;
        public string dataPath = string.Empty;

        /// <summary>
        /// 파일디비초기화작업(클라이언트 갯수만큼 버퍼를 확보한다)
        /// </summary>
        public DatabaseManagerCount()
        {
            LastFileName = string.Empty;
        }

        public Boolean UpdateCountDate(DateTime jobStartTime, int shutIndex, int slotIndex, int count = 1)
        {
            //대상파일을 설정한다.
            var fileName = System.IO.Path.Combine(AR.SETTING.Data.GetDataPath(), "Count",
                jobStartTime.Year.ToString("0000"),
                jobStartTime.Month.ToString("00"),
                jobStartTime.Day.ToString("00"),
                "S" + (shutIndex == 0 ? "F" : "B") + "_" + slotIndex.ToString("0000") + ".xml");
            return UpdateCount(fileName, "", count);
        }

        public Boolean UpdateCountDM(string DataMatrix, int count = 1)
        {
            string ww, seq;
            PUB.splitID(DataMatrix, out ww, out seq);

            //대상파일을 설정한다.
            try
            {
                var fileName = "";
                if (seq.Length > 2)
                {
                    fileName = System.IO.Path.Combine(this.dataPath, "Count", ww, seq.Substring(0, 2), seq + ".xml");
                }
                else
                    fileName = System.IO.Path.Combine(this.dataPath, "Count", ww, seq + ".xml");

                return UpdateCount(fileName, DataMatrix, count);
            }
            catch (Exception ex)
            {
                PUB.log.AddE("UpdateCountDM(" + DataMatrix + ") " + ex.Message);
                return false;
            }
        }

        public enum eCountTarget
        {
            Year = 0,
            Month,
            Day
        }


        /// <summary>
        /// 전체수량을 업데이트 합니다.
        /// </summary>
        public void AddTotalCount(UInt32 New, UInt32 Good, UInt32 Over, UInt32 Err, UInt32 Empty, string modelName)
        {
            AddTotalCount(eCountTarget.Year, New, Good, Over, Err, Empty, "");
            AddTotalCount(eCountTarget.Month, New, Good, Over, Err, Empty, "");
            AddTotalCount(eCountTarget.Day, New, Good, Over, Err, Empty, "");

            //모델별로 추가 기록을 해준다
            if (modelName != "")
            {
                AddTotalCount(eCountTarget.Year, New, Good, Over, Err, Empty, modelName);
                AddTotalCount(eCountTarget.Month, New, Good, Over, Err, Empty, modelName);
                AddTotalCount(eCountTarget.Day, New, Good, Over, Err, Empty, modelName);
            }
            
            //기존값에 해당값을 누적만 시킨다.
        }
        private void AddTotalCount(eCountTarget target, UInt32 New, UInt32 good, UInt32 Over, UInt32 Err, UInt32 Empty, string modelName)
        {
            DateTime dt = DateTime.Now;
            var filename = "";
            if (target == eCountTarget.Year)
            {
                filename = System.IO.Path.Combine(this.dataPath, "Count",
                dt.Year.ToString("0000"), "count.xml");
            }
            else if (target == eCountTarget.Month)
            {
                filename = System.IO.Path.Combine(this.dataPath, "Count",
                dt.Year.ToString("0000"),
                dt.Month.ToString("00"), "count.xml");
            }
            else if (target == eCountTarget.Day)
            {
                filename = System.IO.Path.Combine(this.dataPath, "Count",
                dt.Year.ToString("0000"),
                dt.Month.ToString("00"),
                dt.Day.ToString("00"), "count.xml");
            }

            var keyname = modelName == "" ? "userdata" : modelName;

            //파일이 없다면 생성한다
            var fi = new System.IO.FileInfo(filename);
            if (fi.Directory.Exists == false) fi.Directory.Create();
            var xml = new AR.XMLHelper(fi.FullName);
            if (xml.Exist() == false) xml.CreateFile();

            var str_new = xml.get_Data(keyname,"cnt_new");
            var str_good = xml.get_Data(keyname, "cnt_good");
            var str_over = xml.get_Data(keyname, "cnt_over");
            var str_empty = xml.get_Data(keyname, "cnt_empty");
            var str_err = xml.get_Data(keyname, "cnt_error");
            if (str_new == "") str_new = "0";
            if (str_good == "") str_good = "0";
            if (str_over == "") str_over = "0";
            if (str_empty == "") str_empty = "0";
            if (str_err == "") str_err = "0";

            var cnt_New = UInt32.Parse(str_new);
            var cnt_good = UInt32.Parse(str_good);
            var cnt_Over = UInt32.Parse(str_over);
            var cnt_Empty = UInt32.Parse(str_empty);
            var cnt_Err = UInt32.Parse(str_err);

            //기존수량에 누적
            cnt_New += New;
            cnt_good += good;
            cnt_Over += Over;
            cnt_Empty += Empty;
            cnt_Err += Err;

            //값을 더해서 다시 기록해준다.
            xml.set_Data(keyname, "cnt_new", (cnt_New).ToString());
            xml.set_Data(keyname, "cnt_good", cnt_good.ToString());
            xml.set_Data(keyname, "cnt_over", cnt_Over.ToString());
            xml.set_Data(keyname, "cnt_empty", cnt_Empty.ToString());
            xml.set_Data(keyname, "cnt_error", cnt_Err.ToString());
            string msg;
            xml.Save(out msg);
        }

        public struct eCountData
        {
            public UInt32 NewCount;
            public UInt32 GoodCount;
            public UInt32 OverCount;
            public UInt32 EmptyCount;
            public UInt32 ErrorCount;
            public UInt32 TotalCount
            {
                get
                {
                    return NewCount + GoodCount + OverCount + EmptyCount + ErrorCount;
                }
            }
            public void clear()
            {
                NewCount = 0;
                GoodCount = 0;
                OverCount = 0;
                EmptyCount = 0;
                ErrorCount = 0;
            }
        }

        public eCountData ReadTotalCount(eCountTarget target,string modelName)
        {
            var cnt = new eCountData();
            cnt.clear();

            DateTime dt = DateTime.Now;
            var fi = "";
            if (target == eCountTarget.Year)
            {
                fi = System.IO.Path.Combine(this.dataPath, "Count",
                dt.Year.ToString("0000"), "count.xml");
            }
            else if (target == eCountTarget.Month)
            {
                fi = System.IO.Path.Combine(this.dataPath, "Count",
                dt.Year.ToString("0000"),
                dt.Month.ToString("00"), "count.xml");
            }
            else if (target == eCountTarget.Day)
            {
                fi = System.IO.Path.Combine(this.dataPath, "Count",
                dt.Year.ToString("0000"),
                dt.Month.ToString("00"),
                dt.Day.ToString("00"), "count.xml");
            }

            var appkey = modelName == "" ? "userdata" : modelName;

            //년도데이터가없다면 처리안함
            if (System.IO.File.Exists(fi))
            {
                var xmlYear = new AR.XMLHelper(fi);
                var str_new = xmlYear.get_Data(appkey,"cnt_new");
                var str_good = xmlYear.get_Data(appkey, "cnt_good");
                var str_over = xmlYear.get_Data(appkey, "cnt_over");
                var str_empty = xmlYear.get_Data(appkey, "cnt_empty");
                var str_err = xmlYear.get_Data(appkey, "cnt_error");

                if (str_new == "") str_new = "0";
                if (str_good == "") str_good = "0";
                if (str_over == "") str_over = "0";
                if (str_empty == "") str_empty = "0";
                if (str_err == "") str_err = "0";

                cnt.NewCount = UInt32.Parse(str_new);
                cnt.GoodCount = UInt32.Parse(str_good);
                cnt.OverCount = UInt32.Parse(str_over);
                cnt.EmptyCount = UInt32.Parse(str_empty);
                cnt.ErrorCount = UInt32.Parse(str_err);
            }

            return cnt;
        }

        //해다 자료가 있다면 수량을 올려주고, 그렇지 않다면 파일을 생성해준다.
        private Boolean UpdateCount(string fileName, string DataMatrix, int count = 1)
        {
            var fi = new System.IO.FileInfo(fileName);

            try
            {
                var xml = new AR.XMLHelper(fileName);
                var newCount = count;
                if (fi.Exists == false)
                {
                    //신규이다
                    if (fi.Directory.Exists == false) fi.Directory.Create();

                    //생성해서 추가한다
                    xml.CreateFile();
                    xml.set_Data("id", DataMatrix);
                    newCount = 2;
                }
                else
                {
                    //기존에 있으므로 수량을 읽어서 증가시킨다.
                    int curCnt;
                    var cntStr = xml.get_Data("count");
                    if (int.TryParse(cntStr, out curCnt) == false)
                    {
                        curCnt = 2;
                        PUB.log.AddE("Failed to read existing usage count. Counter string=" + cntStr + ". Setting to default value(1)");
                    }
                    newCount = curCnt + newCount;
                }
                xml.set_Data("count", newCount.ToString());

                //이수량입력되는 시점의 데이터를 기록한다  200117
                string saveMssage;
                xml.set_Data("History" + newCount.ToString("000"), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                xml.Save(out saveMssage);

                LastFileName = fileName;
                return true;
            }
            catch
            {
                return false;
            }
        }
        

        /// <summary>
        /// 지정된 파일의 모든 내용을 읽어서 DataTable 로 반환합니다.
        /// </summary>
        /// <param name="files"></param>
        /// <returns></returns>
        public Dictionary<String, int> GetDatas(int sYear, int sWorkWeek, int eYear, int eWorkWeek, string searchDataMatrix = "")
        {
            var retval = new Dictionary<String, int>();
            //모든파일을 대상으로한다.

            List<System.IO.FileInfo> retfiles = new List<System.IO.FileInfo>();

            //날짜사이의 모든 파일을 대상으로해야함
            int sy = sYear;
            int ey = eYear;
            int sw = sWorkWeek;
            int ew = eWorkWeek;

            int eym = ey * 100 + ew;
            int sym = sy * 100 + sw;

            Boolean endtast = false;
            for (int y = sy; y <= ey; y++)
            {
                var yPath = System.IO.Path.Combine(dataPath, "Count", y.ToString("0000"));
                if (System.IO.Directory.Exists(yPath) == false) continue;

                for (int w = 1; w <= 50; w++)
                {
                    var ym = y * 100 + w;
                    if (ym == eym) endtast = true; //마지막 날짜이다.
                    if (ym < sym) continue; //이전 WW는 넘어간다

                    var path = new System.IO.DirectoryInfo(System.IO.Path.Combine(yPath, w.ToString("00")));
                    if (path.Exists == false) continue; //경로가 없다면 처리하지 않음

                    //검색할 파일 혹은 조건을 생성
                    var searchFileName = (searchDataMatrix == "") ? "*.xml" : (searchDataMatrix + ".xml");

                    var files = path.GetFiles(searchFileName, System.IO.SearchOption.TopDirectoryOnly);
                    foreach (var file in files)
                    {
                        try
                        {
                            var xml = new AR.XMLHelper(file.FullName);
                            var id = xml.get_Data("id");
                            int curCnt;
                            var cntStr = xml.get_Data("count");
                            if (int.TryParse(cntStr, out curCnt) == false)
                            {
                                curCnt = 1;
                                PUB.log.AddE("Failed to read existing usage count. Counter string=" + cntStr + ". Setting to default value(1)");
                            }
                            retval.Add(id, curCnt);
                        }
                        catch (Exception ex)
                        {
                            PUB.log.AddE("database count getdata" + ex.Message);
                        }
                    }

                    if (endtast)
                        break; // TODO: might not be correct. Was : Exit For
                }
                if (endtast)
                    break; // TODO: might not be correct. Was : Exit For
            }
            return retval;
        }

    }
}
