using System;
using System.Data;
using System.IO;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;
using static iMESCore.DataBase.iMESSql;

namespace AutoLoaderLib_C
{

    public class ParsePR : EPIParseTemplate
    {


        // 呼叫父類別的建構子
        public ParsePR(string paramSourcePath, string paramDestinationPath, string paramQueuePath, string paramFailPath) : base(paramSourcePath, paramDestinationPath, paramQueuePath, paramFailPath)
        {

        }

        /// <summary>
    /// 設定暫存資料表的欄位
    /// </summary>
    /// <param name="dt"></param>
    /// <returns></returns>
    /// <remarks></remarks>
        internal override bool AddColumns(DataTable dt)
        {

            bool blnResult = false;

            try
            {

                dt.Columns.Add("WaferID", Type.GetType("System.String"));
                dt.Columns.Add("RawData", Type.GetType("System.String"));
                dt.Columns.Add("Average", Type.GetType("System.Decimal"));
                dt.Columns.Add("Diff1", Type.GetType("System.Decimal"));
                dt.Columns.Add("Diff2", Type.GetType("System.Decimal"));
                dt.Columns.Add("PR_GRADE", Type.GetType("System.String"));
                dt.Columns.Add("PR_RESULT", Type.GetType("System.String"));

                blnResult = true;
            }

            catch (Exception ex)
            {

                throw;

            }

            return blnResult;

        }

        /// <summary>
    /// 將暫存資料表寫入資料庫
    /// </summary>
    /// <param name="dt"></param>
    /// <returns></returns>
    /// <remarks></remarks>
        internal override bool InsertTable(DataTable dt)
        {

            bool blnResult = false;
            string strSQL;
            string strSQL2;
            string strSQL3;

            const string PR_GRADE = "PR Grade";

            // 新增 PR 資料
            strSQL = " INSERT INTO TBL_LEDLD_PR " + "             (WaferID, CreateDate, RawData, Average, Diff1, Diff2, PR_GRADE, PR_RESULT) " + " VALUES      ('{0}', SYSDATE, '{1}', {2}, {3}, {4}, '{5}', '{6}') ";


            // 刪除 ComponentProperty PR_GRADE 的資料
            strSQL2 = " DELETE TBLWIPCOMPONENTPROPERTY " + " WHERE  LOTNO = '{0}' " + " AND    COMPONENTNO = '{1}' " + " AND    PROPERTYNO = '{2}' ";



            // 新增 ComponentProperty PR_GRADE 的資料
            strSQL3 = " INSERT INTO TBLWIPCOMPONENTPROPERTY " + "             (LOTNO, COMPONENTNO, PROPERTYNO, PROPERTYVALUE) " + " VALUES      ('{0}', '{1}', '{2}', '{3}') ";


            try
            {

                using (var oTran = objConnection.BeginTransaction())
                {

                    try
                    {

                        using (var cmd = CreateCommand())
                        {

                            cmd.Connection = objConnection;
                            cmd.Transaction = oTran;

                            for (int i = 0, loopTo = dt.Rows.Count - 1; i <= loopTo; i++)
                            {

                                cmd.CommandText = string.Format(strSQL, Operators.ConcatenateObject(dt.Rows[i]["WaferID"], ""), Operators.ConcatenateObject(dt.Rows[i]["RawData"], ""), dt.Rows[i]["Average"], dt.Rows[i]["Diff1"], dt.Rows[i]["Diff2"], Operators.ConcatenateObject(dt.Rows[i]["PR_GRADE"], ""), Operators.ConcatenateObject(dt.Rows[i]["PR_RESULT"], ""));







                                cmd.ExecuteNonQuery();

                                cmd.CommandText = string.Format(strSQL2, Strings.Mid(Conversions.ToString(Operators.ConcatenateObject(dt.Rows[i]["WaferID"], "")), 1, 10), Operators.ConcatenateObject(dt.Rows[i]["WaferID"], ""), PR_GRADE);



                                cmd.ExecuteNonQuery();

                                cmd.CommandText = string.Format(strSQL3, Strings.Mid(Conversions.ToString(Operators.ConcatenateObject(dt.Rows[i]["WaferID"], "")), 1, 10), Operators.ConcatenateObject(dt.Rows[i]["WaferID"], ""), PR_GRADE, Operators.ConcatenateObject(dt.Rows[i]["PR_GRADE"], ""));




                                cmd.ExecuteNonQuery();

                            }

                        }

                        oTran.Commit();

                        blnResult = true;
                    }

                    catch (Exception ex)
                    {

                        oTran.Rollback();
                        throw;

                    }

                }
            }

            catch (Exception ex)
            {

                throw;

            }

            return blnResult;

        }

        /// <summary>
    /// 解析資料, 並寫入暫存資料表
    /// </summary>
    /// <param name="dt"></param>
    /// <param name="file"></param>
    /// <returns></returns>
    /// <remarks></remarks>
        internal override bool ParsingFile(DataTable dt, string file)
        {

            bool blnResult = false;
            DataRow dr = null;
            string line;
            string[] tmpData;
            string WaferID;
            string RawData = "";
            decimal Average = 0m;
            decimal Diff1 = 0m;
            decimal Diff2 = 0m;
            string PR_Grade;
            string PR_Result;

            try
            {

                // 檔名即為 WaferID
                var fi = new FileInfo(file);
                WaferID = fi.Name.Replace(fi.Extension, "");
                fi = null;

                using (var sr = new StreamReader(file))
                {

                    do
                    {

                        line = sr.ReadLine();

                        if (!string.IsNullOrEmpty(line))
                        {

                            tmpData = line.Split('\t');

                            if (tmpData != null && tmpData.Length == 2)
                            {

                                if (!Information.IsNumeric(tmpData[1]))
                                {
                                    tmpData[1] = "0";
                                }

                                switch (tmpData[0].ToUpper() ?? "")
                                {

                                    case "AVERAGE":
                                        {
                                            Average = Convert.ToDecimal(tmpData[1]);
                                            break;
                                        }

                                    case "DIFF1":
                                        {
                                            Diff1 = Convert.ToDecimal(tmpData[1]);
                                            break;
                                        }

                                    case "DIFF2":
                                        {
                                            Diff2 = Convert.ToDecimal(tmpData[1]);
                                            break;
                                        }

                                    default:
                                        {
                                            RawData += tmpData[0] + "=" + tmpData[1] + ",";
                                            break;
                                        }

                                }

                            }

                        }
                    }

                    while (!string.IsNullOrEmpty(line));

                    if (RawData.Length > 0)
                    {

                        RawData = RawData.Substring(0, RawData.Length - 1);

                        // 依 Average 取出 Grade
                        PR_Grade = PRGrade(Average);

                        if (string.IsNullOrEmpty(PR_Grade))
                        {
                            throw new Exception("PR_Grade fail。");
                        }

                        // 依 Diff 取出 Grade
                        switch (PRGrade(Diff1) ?? "")
                        {
                            case "":
                                {
                                    throw new Exception("PR_Result fail。");
                                }
                            case "N/A":
                                {
                                    PR_Result = "NG";
                                    break;
                                }

                            default:
                                {
                                    PR_Result = "OK";
                                    break;
                                }
                        }

                        dr = dt.NewRow();
                        dr["WaferID"] = WaferID;
                        dr["RawData"] = RawData;
                        dr["Average"] = Average;
                        dr["Diff1"] = Diff1;
                        dr["Diff2"] = Diff2;
                        dr["PR_GRADE"] = PR_Grade;
                        dr["PR_RESULT"] = PR_Result;
                        dt.Rows.Add(dr);

                        blnResult = true;

                    }

                }
            }

            catch (Exception ex)
            {

                throw;
            }

            finally
            {

                if (dr != null)
                {
                    dr = null;
                }

            }

            return blnResult;

        }

        /// <summary>
    /// PR 等級編碼原則
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    /// <remarks></remarks>
        private string PRGrade(decimal value)
        {

            string strGrade = "N/A";
            string[] tmpData;
            var CollectionGrade = new Collection();

            CollectionGrade.Add("0~1.5~A1");
            CollectionGrade.Add("1.5~2~A2");
            CollectionGrade.Add("2~3~A3");
            CollectionGrade.Add("3~6~A4");
            CollectionGrade.Add("6~9~A5");
            CollectionGrade.Add("9~12~A6");
            CollectionGrade.Add("12~15~A7");
            CollectionGrade.Add("15~18~A8");
            CollectionGrade.Add("18~24~A9");
            CollectionGrade.Add("24~30~AA");
            CollectionGrade.Add("30~36~AB");
            CollectionGrade.Add("36~9999~AC");

            try
            {

                foreach (string str in CollectionGrade)
                {

                    tmpData = Strings.Split(str, "~");

                    if (tmpData.Length != 3)
                    {
                        break;
                    }

                    if (!Information.IsNumeric(tmpData[0]) || !Information.IsNumeric(tmpData[1]))
                    {
                        break;
                    }

                    if ((double)value >= Conversions.ToDouble(tmpData[0]) && (double)value < Conversions.ToDouble(tmpData[1]))
                    {
                        strGrade = tmpData[2];
                        break;
                    }

                }
            }

            catch (Exception ex)
            {

                strGrade = "";

            }

            return strGrade;

        }

    }
}