using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraGrid.Views.Grid;
using SystemX.Product.ALIS.UI.View.InfoList;
using System.Data.SqlClient;
using SystemX.Product.ALIS.Interface;
using static SystemX.Product.ALIS.UI.View.ViewCfg;
using DevExpress.XtraGrid.Columns;
using System.Reflection;
using SystemX.Product.ALIS.UI.Subs;
using System.Threading;

using static CpCommon.ExceptionHandler;
using static PsKGaudi.Parser.PsCCS;
using PsKGaudi.Parser.PsCCSSTDFn;
using CpApplication;
using CpApplication.Manager;
using CpCommon;
using CpTesterPlatform.CpLogUtil;
using static PsCommon.PsCommon;
using System.Xml.Linq;
using PsKGaudi.Parser.PsCCSArea;
using PsKGaudi;
using PsKGaudi.Parser.MacroModuleSkel;
using PsKGaudi.Parser.PsCCSSTDFn.Parameters;
using DevExpress.XtraGrid.Views.Base;
using PsKGaudi.Parser.PsCCSSTDFn;
using System.IO;
using static SystemX.Net.Platform.Common.Util.LogMessage;
using System.Diagnostics;
using SystemX.Common;
using SystemX.Common.Archive;

namespace SystemX.Product.ALIS.UI.View.InfoList
{
    public class UcTestListViewFileBasicWorker
    {

    }

    public partial class UcTestListView
    {
        /// <summary>
        /// 
        /// </summary>
        private void RunAsyncFileInsertUpdateWorker()
        {
            workerTestListFile.RunWorkerAsync(eEdtType);

            loadForm = new WaitProgressForm();
            loadForm.setDescription("Proceeding ...");
            loadForm.Location = new Point(this.Parent.Width / 2, this.Parent.Height / 2);

            stLoadFormWait.Restart();
            loadForm.ShowDialog();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="strSetTableName"></param>
        /// <returns></returns>
        private int PerformNewVRFYTestListFileRelease(string strSetTableName)
        {
            int iItemNum = SelectTestListFileInfo.TestListFileSelectGaudiData.ListTestStep.Count;
            int iPos = 0;

            int isetVersion = 0;
            int isetEnable = 1;

            SqlBulkCopy sbc = new SqlBulkCopy(ctrlDB.GetConnSqlCmd().Connection);
            sbc.BatchSize = 5000;
            sbc.DestinationTableName = strSetTableName; // "dbo.VRFY_TestListFileRelease";
            sbc.BulkCopyTimeout = 300;

            DataTable SetVRFYReleaseTable;
            SetVRFYReleaseTable = MakeVRFYTestListReleaseTable();

            DataRow[] SetMakeVRFYReleaseRows = new DataRow[iItemNum];
            DateTime dtNewTime = ctrlDB.GetServerDateTime();

            PsCCSStdFnBase fbdsd = null;
            foreach (PsCCSStdFnBase fb in SelectTestListFileInfo.TestListFileSelectGaudiData.ListTestStep)
            {
                try
                {
                    fb.GetTestStepSummary();

                    fbdsd = fb;

                    string strMO = (fb.GetMO() != null) ? fb.GetMO() : "";
                    string strFuncName = (fb.GetSTDFnNameAsEnum().ToString() != null) ? fb.GetSTDFnNameAsEnum().ToString() : "";
                    string strDim = (fb.GetDimension().ToString() != null) ? fb.GetDimension().ToString() : "";

                    string[] strSummaryTestSteps = fb.SummaryTestStep;
                    string strMacroParm = (strSummaryTestSteps[6] != null) ? strSummaryTestSteps[6] : "";
                    string strParm = (strSummaryTestSteps[8] != null) ? strSummaryTestSteps[8] : "";

                    string strGetMin = (fb.PairedParmsMinMax.Min != null) ? fb.PairedParmsMinMax.Min : "";
                    string strGetMax = (fb.PairedParmsMinMax.Max != null) ? fb.PairedParmsMinMax.Max : "";

                    SetMakeVRFYReleaseRows[iPos] = SetVRFYReleaseTable.NewRow();
                    SetMakeVRFYReleaseRows[iPos]["TestlistNo"] = SelectTestListFileInfo.SelectTestListFileNo.Value;
                    SetMakeVRFYReleaseRows[iPos]["StepID"] = fb.StepNum;
                    SetMakeVRFYReleaseRows[iPos]["Variant"] = fb.Variant;
                    SetMakeVRFYReleaseRows[iPos]["Gate"] = fb.Gate;

                    PsKGaudi.Parser.PsCCSDefineEnumTraceability getTracebility = fb.Traceability;
                    PsKGaudi.Parser.PsCCSDefineEnumActivate getActivateState = fb.IsActivate();
                    PsKGaudi.Parser.PsCCSDefineEnumActivate getActivateProperty = fb.Activate;

                    if (getActivateProperty == PsKGaudi.Parser.PsCCSDefineEnumActivate.ACTIVATE)
                        SetMakeVRFYReleaseRows[iPos]["Activate"] = 1;
                    else
                        SetMakeVRFYReleaseRows[iPos]["Activate"] = 0;

                    SetMakeVRFYReleaseRows[iPos]["StepVersion"] = isetVersion;
                    SetMakeVRFYReleaseRows[iPos]["Enable"] = isetEnable;
                    SetMakeVRFYReleaseRows[iPos]["Position"] = fb.Position;
                    SetMakeVRFYReleaseRows[iPos]["StepDesc"] = strMO;
                    SetMakeVRFYReleaseRows[iPos]["UseFunction"] = strFuncName;
                    SetMakeVRFYReleaseRows[iPos]["MacroParm"] = strMacroParm;
                    SetMakeVRFYReleaseRows[iPos]["Parm"] = strParm;
                    SetMakeVRFYReleaseRows[iPos]["SpecMin"] = strGetMin;
                    SetMakeVRFYReleaseRows[iPos]["SpecMax"] = strGetMax;

                    if (fb.PairedParmsMinMax.Min.IndexOf("&") >= 0 || fb.PairedParmsMinMax.Max.IndexOf("&") >= 0)
                        SetMakeVRFYReleaseRows[iPos]["IsGlobal"] = 1;
                    else
                        SetMakeVRFYReleaseRows[iPos]["IsGlobal"] = 0;

                    SetMakeVRFYReleaseRows[iPos]["Dim"] = strDim;
                    SetMakeVRFYReleaseRows[iPos]["UpdateDT"] = dtNewTime;

                    iPos += 1;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"PerformTestListReading [New] - Read Step fail. [SystemX.Product.ALIS.UI.View.InfoList : UcTestListView.PerformTestListReading]\r\n" + ex.Message, ConsoleColor.Red, LogMessageLevel.FATAL);
                }
            }
            //
            try
            {
                // Write from the source to the destination.
                sbc.WriteToServer(SetMakeVRFYReleaseRows);
            }
            catch (Exception ex)
            {
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"PerformTestListReading [New] DB-Update fail. [SystemX.Product.ALIS.UI.View.InfoList : UcTestListView.PerformTestListReading]\r\n" + ex.Message, ConsoleColor.Red, LogMessageLevel.FATAL);
            }
            finally
            {
                // Close the SqlDataReader. The SqlBulkCopy
                // object is automatically closed at the end
                // of the using block.
            }

            return 0;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void PerformTestListFileReading(object sender, DoWorkEventArgs args)
        {
            if (SelectOpenType != eSelectType.TestListFile)
                return;

            Thread.Sleep(10);

            bool bBinaryCompareResult = false;
            bool bProcessResult = true;

            eEditType eSeledtType = (eEditType)((System.ComponentModel.DoWorkEventArgs)args).Argument;

            Stopwatch stMeasTime = new Stopwatch();
            stMeasTime.Start();

            string strSetVRFYReleaseTableName = "VRFY_TestListFileRelease";
            string strSetMaxStepVersionTableName = "HIST_TestListFileLatestStepVersion";
            string strSetTestLIstFileVariantList = "HIST_TestListFileVariantList";

            int nGetMaxStepVersion = int.MaxValue;

            try
            {
                switch (eSeledtType)
                {
                    case eEditType.Insert:
                        MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @" PerformTestListFileReading() Insert", ConsoleColor.Yellow, LogMessageLevel.DEBUG);

                        PerformNewVRFYTestListFileRelease(strSetVRFYReleaseTableName);
                        break;
                    case eEditType.Modify:
                        if (SelectTestListFileInfo.TestListFileLoadRawData.Length == 0)
                            throw new Exception();

                        //Binary 상태 비교
                        //동일한 파일(변경점이 없을시) 미진행 
                        if (Commons.ByteArrayCompare(SelectTestListFileInfo.TestListFileLoadRawData, SelectTestListFileInfo.TestListFileSelectRawData) == true)
                        {
                            MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @" PerformTestListFileReading() ByteArrayCompare Result = true", ConsoleColor.Yellow, LogMessageLevel.DEBUG);

                            bBinaryCompareResult = true;
                        }
                        else
                        {
                            //Stopwatch stLoadTimeCheck = new Stopwatch();
                            //stLoadTimeCheck.Start();

                            //기존 정보
                            PsCCSGaudiFile orgFile = SelectTestListFileInfo.TestListFileLoadGaudiData; //TemporaryTestListLoad(SelectTestListFileInfo.TestListFileLoadRawData);

                            //새로운 정보
                            PsCCSGaudiFile newFile = SelectTestListFileInfo.TestListFileSelectGaudiData; //TemporaryTestListLoad(SelectTestListFileInfo.TestListFileSelectRawData);

                            //long lTimeChk = stLoadTimeCheck.ElapsedMilliseconds;

                            //새 정보에서의 차집합 
                            List<PsCCSStdFnBase> fbaseNewChg = newFile.ListTestStep.Except(orgFile.ListTestStep, new PsCCSStdFnBaseDataCompare()).ToList();

                            //기존 정보에서의 차집합
                            List<PsCCSStdFnBase> fbaseOldChg = orgFile.ListTestStep.Except(newFile.ListTestStep, new PsCCSStdFnBaseDataCompare()).ToList();

                            //전체 변경 항목(추가/삭제 항목 포함)
                            List<PsCCSStdFnBase> changeAllItem = fbaseNewChg.Except(fbaseOldChg, new PsCCSStdFnBaseDataCompare()).ToList();

                            //삭제된 항목
                            List<PsCCSStdFnBase> deleteItem = fbaseOldChg.Except(fbaseNewChg, new PsCCSStdFnBaseDataCompare(false)).ToList();

                            //추가된 항목
                            List<PsCCSStdFnBase> newItem = fbaseNewChg.Except(fbaseOldChg, new PsCCSStdFnBaseDataCompare(false)).ToList();

                            //변경된 항목
                            List<PsCCSStdFnBase> setChgItem = changeAllItem.Except(newItem, new PsCCSStdFnBaseDataCompare()).ToList();
                            setChgItem = setChgItem.Except(deleteItem, new PsCCSStdFnBaseDataCompare()).ToList();

                            DateTime dtsetTime = DateTime.Now;

                            //수정 -> 삭제 -> 추가
                            //현재 마지막 버전 확인
                            MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @" PerformTestListFileReading() Get SelectTestListFileNo", ConsoleColor.Yellow, LogMessageLevel.DEBUG);

                            int nTestListdFileNo = SelectTestListFileInfo.SelectTestListFileNo.Value;
                            int nLastVersion = -1;

                            MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @" PerformTestListFileReading() SelectTestListFileNo = " + nTestListdFileNo, ConsoleColor.Yellow, LogMessageLevel.DEBUG);

                            ctrlDB.GetConnSqlCmd().CommandText = "SELECT MAX(StepVersion) AS 'Latest Version' FROM [" + strSetVRFYReleaseTableName + "] WHERE TestListFileNo = " + nTestListdFileNo + ";";
                            nLastVersion = Convert.ToInt32(ctrlDB.GetConnSqlCmd().ExecuteScalar());

                            MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @" PerformTestListFileReading() Current Last StepVersion = " + nLastVersion, ConsoleColor.Yellow, LogMessageLevel.DEBUG);

                            SetVRFYReleaseTableControl(eVRFYControlMode.Change, nTestListdFileNo, dtsetTime, setChgItem, nLastVersion);
                            SetVRFYReleaseTableControl(eVRFYControlMode.Delete, nTestListdFileNo, dtsetTime, deleteItem, nLastVersion);
                            SetVRFYReleaseTableControl(eVRFYControlMode.Insert, nTestListdFileNo, dtsetTime, newItem, nLastVersion);
                        }
                        break;
                }

                ctrlDB.GetConnSqlCmd().CommandText = "SELECT MAX(StepVersion) AS 'Latest Version' FROM [" + strSetVRFYReleaseTableName + "] WHERE TestListFileNo = " + SelectTestListFileInfo.SelectTestListFileNo.Value + ";";

                nGetMaxStepVersion = Convert.ToInt32(ctrlDB.GetConnSqlCmd().ExecuteScalar());

                switch (eSeledtType)
                {
                    case eEditType.Insert:
                        ctrlDB.GetConnSqlCmd().CommandText = "INSERT INTO [" + strSetMaxStepVersionTableName + "] (TestListFileNo, LatestStepVersion) VALUES" +
                            "(" + SelectTestListFileInfo.SelectTestListFileNo.Value + ", " + nGetMaxStepVersion + ");";
                        break;
                    case eEditType.Modify:
                        ctrlDB.GetConnSqlCmd().CommandText = "UPDATE [" + strSetMaxStepVersionTableName + "] SET LatestStepVersion = " + nGetMaxStepVersion +
                        " WHERE TestListFileNo = " + SelectTestListFileInfo.SelectTestListFileNo.Value + ";";
                        break;
                }
                //
                try
                {
                    int EffectRows = ctrlDB.GetConnSqlCmd().ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @" PerformTestListFileReading() - LatestStepVersion SqlCommand Update Error. " + ex.Message, ConsoleColor.Red, LogMessageLevel.FATAL);

                    throw;
                }
                //
                switch (eSeledtType)
                {
                    case eEditType.Insert:
                        ctrlDB.GetConnSqlCmd().CommandText = "INSERT INTO [" + strSetTestLIstFileVariantList + "] (TestListFileNo, VariantList) VALUES" +
                            "(" + SelectTestListFileInfo.SelectTestListFileNo.Value + ", '" + string.Join(";", SelectTestListFileInfo.VariantList.ToArray()) + "');";
                        break;
                    case eEditType.Modify:
                        ctrlDB.GetConnSqlCmd().CommandText = "UPDATE [" + strSetTestLIstFileVariantList + "] SET VariantList = '" + string.Join(";", SelectTestListFileInfo.VariantList.ToArray()) + "'" +
                        " WHERE TestListFileNo = " + SelectTestListFileInfo.SelectTestListFileNo.Value + ";";
                        break;
                }
                //
                try
                {
                    int EffectRows = ctrlDB.GetConnSqlCmd().ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @" PerformTestListFileReading() - VariantList SqlCommand Update Error. " + ex.Message, ConsoleColor.Red, LogMessageLevel.FATAL);

                    throw;
                }
            }
            catch (Exception error)
            {
                bProcessResult = false;

                MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @" PerformTestListFileReading() Common Error. " + error.Message, ConsoleColor.Red, LogMessageLevel.FATAL);
            }
            finally
            {
                var setResult = new Tuple<eEditType, bool, bool, int>(eSeledtType, bBinaryCompareResult, bProcessResult, nGetMaxStepVersion);

                args.Result = setResult;
            }

            long lMeasTime = stMeasTime.ElapsedMilliseconds;
        }

        private async void ReadingFileCompleted(object sender, RunWorkerCompletedEventArgs args)
        {
            // Error Check
            if (args.Error != null)
            {
                ;//
            }
            // Worker Cancel
            else if (args.Cancelled)
            {
                ;//
            }
            // Success
            else
            {
                var getResult = args.Result as Tuple<eEditType, bool, bool, int>;

                eEditType getType = getResult.Item1;
                bool bGetCompareResult = getResult.Item2;
                bool bGetProcessResult = getResult.Item3;
                int iGetMaxStepVersion = getResult.Item4;

                //정상 처리 상태 일때만.
                if (bGetProcessResult)
                {
                    switch (getType)
                    {
                        case eEditType.Insert:
                            ;//
                            break;
                        case eEditType.Modify:
                            {
                                //테스트 리스트 데이터가 같고 그외 내용이 변경되었거나 그대로일 경우 우선 업데이트 진행.
                                if (bGetCompareResult == true)
                                    SqlUpdateProdTestListFile(iGetMaxStepVersion);
                                //테스트 리스트 데이터 까지 변경
                                else
                                    SqlUpdateProdTestListFile(iGetMaxStepVersion, true);
                            }
                            break;
                    }
                }
            }

            if (stLoadFormWait.ElapsedMilliseconds <= 1000)
            {
                int iremainTime = 1000 - (int)stLoadFormWait.ElapsedMilliseconds;

                await Task.Delay(iremainTime); //Thread.Sleep(iremainTime); 
            }

            if (loadForm != null)
            {
                loadForm.Close();
                loadForm = null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iMaxStepVersion"></param>
        /// <param name="bHistTestListFileDataShift"></param>
        private void SqlUpdateProdTestListFile(int nMaxStepVersion, bool bHistTestListFileDataShift = false)
        {
            bool bUpdatedResult = true;

            string strSetRegDT, strSetUpdateDT;

            strSetRegDT = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            strSetUpdateDT = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");

            string columns = string.Empty;

            columns = "Name,TestType,Version,ProdCode,FileName,RegDT,RegUser,UpdateDT,UpdateUser,Comment,Description,TestListData";

            Type type = typeof(CTestListFileInformation);
            FieldInfo[] f = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            StringBuilder sb = new StringBuilder();
            sb.Append("UPDATE [" + strSelectTable + "] SET ");

            foreach (string str in columns.Split(','))
            {
                int idx = -1;
                idx = Array.FindIndex(f, x => x.Name.IndexOf(str) >= 0);

                if (str == "TestListData")
                {
                    byte[] ucWriteTestList = XDataArchive.CompressGZipByteToByte(SelectTestListFileInfo.TestListFileSelectRawData);

                    string strGetBytes = "0x" + string.Concat(Array.ConvertAll(ucWriteTestList, byt => byt.ToString("X2")));

                    sb.Append(str + " = " + strGetBytes + ", ");
                }
                else if (str == "RegDT" || str == "UpdateDT")
                {
                    string strGetDateTime = ctrlDB.SetConvertDateTime(f[idx].GetValue(SelectTestListFileInfo).ToString());

                    sb.Append(str + " = '" + strGetDateTime + "', ");

                    if (str == "RegDT")
                        strSetRegDT = strGetDateTime;
                    else if (str == "UpdateDT")
                        strSetUpdateDT = strGetDateTime;
                }
                else
                    sb.Append(str + " = '" + f[idx].GetValue(SelectTestListFileInfo) + "', ");
            }
            sb = sb.Remove(sb.Length - 2, 1);
            sb.Append("WHERE No = " + AbsoluteUniqueNo + ";");

            using (SqlCommand cmd = new SqlCommand(sb.ToString(), ctrlDB.GetConnSqlCmd().Connection))
            {
                try
                {
                    int EffectRows = cmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    bUpdatedResult = false;

                    MessageBox.Show(ex.Message, "SqlUpdateProdTestListFile [" + strSelectTable + "] - Error[1]", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            if (bUpdatedResult)
            {
                //테스트리스트 파일에 연결된 Variant TL-Position 0 으로 변경
                DataTable dtQueryResult = ctrlDB.GetTable($"SELECT No FROM [CPXV2].[dbo].[PROD_Variant] WITH(NOLOCK) WHERE TestListFileNo = {AbsoluteUniqueNo};");

                if (XCommons.isHasRow(dtQueryResult))
                {
                    foreach (DataRow dr in dtQueryResult.Rows)
                    {
                        int nRefVariantNo = int.Parse(dr["No"].ToString());

                        string strSetUpdateText = $"UPDATE [CPXV2].[dbo].[PROD_Variant] SET UseTLPosition = 0 WHERE No = {nRefVariantNo};";

                        using (SqlCommand cmd = new SqlCommand(strSetUpdateText, ctrlDB.GetConnSqlCmd().Connection))
                        {
                            try
                            {
                                int EffectRows = cmd.ExecuteNonQuery();
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message, "SqlUpdateProdTestListFile [HIST_TestListFile] - Error[2]", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                    }
                }

                //업데이트 결과가 정상이고 두번 이상의 업데이트가 일어났을때 HIST_TestListFile 등록 및 데이터 업데이트(쉬프트 시작)
                if (bHistTestListFileDataShift == false)
                    return;
            }
            if (bUpdatedResult && nMaxStepVersion > 0)
            {
                string strQueryText = $"SELECT No, TestListFileNo, Name FROM [HIST_TestListFile] WHERE TestListFileNo = {AbsoluteUniqueNo};"; // AND Name = '{SelectTestListFileInfo.Name}';";

                DataTable dtQuery = ctrlDB.GetTable(strQueryText);

                try
                {
                    if (XCommons.isHasRow(dtQuery) == false)
                    {
                        strQueryText = $"INSERT INTO [HIST_TestListFile] (TestListFileNo, Name) VALUES({AbsoluteUniqueNo}, '-');"; //'{SelectTestListFileInfo.Name}');";

                        using (SqlCommand cmd = new SqlCommand(strQueryText, ctrlDB.GetConnSqlCmd().Connection))
                        {
                            int EffectRows = cmd.ExecuteNonQuery();
                        }
                    }
                }
                catch (Exception ex)
                {
                    bUpdatedResult = false;

                    MessageBox.Show(ex.Message, "SqlUpdateProdTestListFile [HIST_TestListFile] - Error[3]", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                HistTestListFileDataUpdate();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private bool HistTestListFileDataUpdate()
        {
            int nHistTestListNum = 10;

            bool bDataShiftResult = true;

            string columns = string.Empty;

            string strQueryText = $"SELECT * FROM [HIST_TestListFile] WHERE TestListFileNo = {AbsoluteUniqueNo};"; // AND Name = '{SelectTestListFileInfo.Name}';";

            DataTable dtQuery = ctrlDB.GetTable(strQueryText);

            if (XCommons.isHasRow(dtQuery) == false)
                return false;

            int nAccessNo = Convert.ToInt32(dtQuery.Rows[0]["No"]);

            bool[] bMoveData = new bool[nHistTestListNum];
            Array.Clear(bMoveData, 0, nHistTestListNum);

            bMoveData[0] = true;

            string[] strTestListDataName = { "TestListData1", "TestListData2", "TestListData3", "TestListData4", "TestListData5", "TestListData6", "TestListData7", "TestListData8", "TestListData9", "TestListData10" };

            string[] strArrGetBytes = new string[nHistTestListNum];

            //Data Check
            for (int i = 0; i < nHistTestListNum; i++)
            {
                if (dtQuery.Rows[0][strTestListDataName[i]] is byte[])
                {
                    if (i + 1 < nHistTestListNum) bMoveData[i + 1] = true;
                }
                else
                    continue;

                byte[] ucWriteTestList = dtQuery.Rows[0][strTestListDataName[i]] as byte[];
                strArrGetBytes[i] = "0x" + string.Concat(Array.ConvertAll(ucWriteTestList, byt => byt.ToString("X2")));
            }

            //Data Ready&Move
            for (int i = nHistTestListNum - 1; i >= 0; i--)
            {
                if (bMoveData[i] == false)
                    continue;

                switch (i)
                {
                    case 0:
                        {
                            byte[] ucWriteTestList = XDataArchive.CompressGZipByteToByte(SelectTestListFileInfo.TestListFileLoadRawData);

                            string strGetBytes = "0x" + string.Concat(Array.ConvertAll(ucWriteTestList, byt => byt.ToString("X2")));

                            strArrGetBytes[i] = strGetBytes;
                        }
                        break;
                    default:
                        strArrGetBytes[i] = strArrGetBytes[i - 1];
                        break;
                }
            }

            //Data Update
            columns = "TestListData1,TestListData2,TestListData3,TestListData4,TestListData5,TestListData6,TestListData7,TestListData8,TestListData9,TestListData10";

            StringBuilder sb = new StringBuilder();

            sb.Append("UPDATE [HIST_TestListFile] SET ");

            int nPos = 0;
            foreach (string str in columns.Split(','))
            {
                if (bMoveData[nPos] == false)
                    continue;

                sb.Append(str + " = " + strArrGetBytes[nPos] + ", ");

                nPos++;
            }

            sb = sb.Remove(sb.Length - 2, 1);
            sb.Append("WHERE No = " + nAccessNo + ";");

            using (SqlCommand cmd = new SqlCommand(sb.ToString(), ctrlDB.GetConnSqlCmd().Connection))
            {
                try
                {
                    int EffectRows = cmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    bDataShiftResult = false;

                    MessageBox.Show(ex.Message, "HistTestListFileDataUpdate [HIST_TestListFile][Data Update] - Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

            return bDataShiftResult;
        }
    }
}
