using DDUtilityApp.DATA;
using DDUtilityApp.LOGPARSER.DATA;
using DDUtilityApp.SECS;
using FluentFTP;
using FluentFTP.Helpers;
using JWH;
using JWH.CONTROL;
using JWH.DATA;
using JWH.NETWORK;
using Org.BouncyCastle.Tls.Crypto;
using Renci.SshNet;
using Renci.SshNet.Sftp;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using Telerik.WinControls.UI;
using static Telerik.WinControls.UI.ValueMapper;

namespace DDUtilityApp.LOGPARSER
{

    public partial class FrmEqSelector : Form
    {

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

        public enum eServerType { EIS, AGV }

        public eServerType ServerType { get; set; } = eServerType.EIS;

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

        /// <summary>
        /// 선택된 로그파일
        /// </summary>
        public LogFile[] SelectedLogFiles { get; set; } = null;

        private LogServer LogServer { get; set; } = null;

        public EisEquipment Equipment { get; set; } = null;

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

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

        #endregion

        #region [ FrmEqSelector ] ---------------------------------------------

        public FrmEqSelector()
        {
            InitializeComponent();
            this.SetLayout();
            this.SetEventHandler();
        }

        public FrmEqSelector(eServerType server) : this()
        {
            this.ServerType = server;
        }

        private void SetLayout()
        {
            Font font = new Font("돋움체", 9);

            this.tboxName.ImeMode = ImeMode.Hangul;
            this.tboxEquipmentID.ImeMode = ImeMode.Alpha;
            this.chkAllEquipment.Checked = GlobalVariable.Instance.FrmEqSelector_AllEquipment;
            this.chkUseSMB.Checked = true;      // = GlobalVariable.Instance.FrmEqSelector_UseSMB
            this.chkUseSMB.Visible = false;
            this.tabControl1.SelectedIndex = 0;
            this.tboxModelDescription.Font = font;

            this.GridEquipments_Setting();
            this.GridLogFiles_Setting(this.gridLogFiles); //jhlim 20250202
            this.GridLogFiles_Setting(this.gridHsms);     //jhlim 20250202
            this.GridLogFiles_Setting(this.gridWorkflow); //jhlim 20250202
            this.GridModelDetail_Setting();
        }

        protected void SetEventHandler()
        {
            this.Load += FrmEquipments_Load;
            this.FormClosing += FrmEqSelector_FormClosing;
            this.FormClosed += this.FrmEqSelector_FormClosed;
            this.Disposed += this.FrmEqSelector_Disposed;

            this.cboxServer.SelectedValueChanged += CboxServer_SelectedValueChanged;
            this.btnOK.Click += BtnOK_Click;
            this.tboxName.KeyDown += TboxFilter_KeyDown;
            this.tboxEquipmentID.KeyDown += TboxFilter_KeyDown;
            this.chkAllEquipment.CheckStateChanged += ChkAllEquipment_CheckStateChanged;

            this.flowLayoutPanel1.DoubleClick += this.FlowLayoutPanel1_DoubleClick;

            this.gridEquipments.SelectionChanged += GridEquipments_SelectionChanged;
            this.gridEquipments.CellDoubleClick += GridEquipments_CellDoubleClick;
            this.gridEquipments.DataBindingComplete += GridEquipments_DataBindingComplete;
            this.gridEquipments.KeyDown += GridEquipments_KeyDown;

            this.gridLogFiles.CellDoubleClick += GridLogFiles_CellDoubleClick;
            this.gridLogFiles.KeyDown += GridLogFiles_KeyDown;

            //jhlim 20250202 start
            this.gridWorkflow.CellDoubleClick += Grid_CellDoubleClick;
            this.gridWorkflow.KeyDown += Grid_KeyDown;
            this.gridHsms.CellDoubleClick += Grid_CellDoubleClick;
            this.gridHsms.KeyDown += Grid_KeyDown;
            //jhlim 20250202 end 
        }

        private void FrmEqSelector_Disposed(object sender, EventArgs e)
        {
            if (this.gridEquipments != null) this.gridEquipments.Dispose();
            if (this.gridLogFiles != null) this.gridLogFiles.Dispose();
            if (this.gridModelDetail != null) this.gridModelDetail.Dispose();
        }

        private void FlowLayoutPanel1_DoubleClick(object sender, EventArgs e)
        {
            this.ControlCapture();
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            try
            {
                switch (keyData)
                {
                    case Keys.F1:
                        Process.Start("IEXPLORE.EXE", "http://pms.e1soft.co.kr:8090/Deploy/eqview/");
                        break;
                    case Keys.F6:
                        this.gridEquipments.BestFitColumns(BestFitColumnMode.DisplayedCells);
                        this.gridLogFiles.BestFitColumns(BestFitColumnMode.DisplayedCells);
                        this.gridModelDetail.BestFitColumns(BestFitColumnMode.DisplayedCells);
                        break;
                }
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void FrmEquipments_Load(object sender, EventArgs e)
        {
            this.SetLogServer();
            if (this.Equipment != null) this.SetEquipment(this.Equipment);
            else this.SetEquipment(this.ServerName, this.Equipment?.EquipmentID);
            this.SetSelectedLogFiles(this.SelectedLogFiles);
        }

        private void FrmEqSelector_FormClosing(object sender, FormClosingEventArgs e)
        {
        }

        private void FrmEqSelector_FormClosed(object sender, FormClosedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            foreach (GridViewColumn column in this.gridEquipments.Columns.OrderBy(x => x.Index))
                if (column.IsVisible) sb.AppendFormat($"{column.Name};");
            GlobalVariable.Instance.FrmEqSelector_GridEquipmentHeader = sb.ToString();
            GlobalVariable.Instance.FrmEqSelector_UseSMB = this.chkUseSMB.Checked;
            GlobalVariable.Instance.SaveSetting();

            if (this.DialogResult == DialogResult.OK)
                this.GetGEMSetting();
        }

        #endregion


        #region [ Control Events ] --------------------------------------------

        private void CboxServer_SelectedValueChanged(object sender, EventArgs e)
        {
            try
            {
                EisEquipment[] equipments = this.GetEquipments();
                if (this.chkAllEquipment.Checked == false)
                    equipments = equipments.Where(x => x.MesRegistration).ToArray();

                this.gridEquipments.AutoBinding(equipments);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex, true);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        /// <summary>
        ///  jhlim 20250202
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.tabControl1.SelectedTab == this.tabHSMS)
                {
                    if (this.gridHsms.DataSource == null) return;

                    string remotePath = $"/{this.Account.DefaultPath}/{this.Equipment.EquipmentID}/THiRA_SECSGEM/HSMS";
                    switch (this.Account.Access)
                    {
                        case AccessType.SMB:
                            break;
                        case AccessType.FTPS:
                            {
                                FtpsClient.Connect();
                                FtpListItem[] items = FtpsClient.GetFtpsList(remotePath);
                                this.gridHsms.AutoBinding(this.GetLogFiles(items));
                                FtpsClient.Disconnect();
                            }
                            break;
                        case AccessType.SFTP:
                            {
                                StpClientWrap.Connect();
                                ISftpFile[] items = (ISftpFile[])StpClientWrap.GetSftpList(remotePath);
                                this.gridHsms.AutoBinding(this.GetLogFiles(items));
                                StpClientWrap.Disconnect();
                            }
                            break;
                        case AccessType.FTP:
                            break;
                    }
                }
                else if (this.tabControl1.SelectedTab == this.tabWorkflow)
                {
                    if (this.gridWorkflow.DataSource != null) return;

                    string remotePath = $"/{this.Account.DefaultPath}/{this.Equipment.EquipmentID}/Workflow";
                    switch (this.Account.Access)
                    {
                        case AccessType.SMB:
                            break;
                        case AccessType.FTPS:
                            {
                                FtpsClient.Connect();
                                FtpListItem[] items = FtpsClient.GetFtpsList(remotePath);
                                LogFile[] logFiles = this.GetLogFiles(items);
                                this.gridWorkflow.AutoBinding(logFiles);
                                FtpsClient.Disconnect();
                            }
                            break;
                        case AccessType.SFTP:
                            {
                                StpClientWrap.Connect();
                                ISftpFile[] items = (ISftpFile[])StpClientWrap.GetSftpList(remotePath);
                                this.gridWorkflow.AutoBinding(this.GetLogFiles(items));
                                StpClientWrap.Disconnect();
                            }
                            break;
                        case AccessType.FTP:
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex, true);
            }
        }

        /// <summary>
        /// [CheckPoint] 로그파일 목록을 반환한다
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnOK_Click(object sender, EventArgs e)
        {
            try
            {
                LogFile logFile = null;
                List<LogFile> list = new List<LogFile>();
                foreach (GridViewRowInfo row in this.gridLogFiles.SelectedRows)
                {
                    logFile = row.DataBoundItem as LogFile;
                    if (logFile == null) continue;
                    list.Add(logFile);
                }

                SelectedLogFiles = list.ToArray();
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex, true);
            }
        }

        private void TboxFilter_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Enter:
                    this.gridEquipments.FilterDescriptors.Remove("DisplayName");
                    this.gridEquipments.FilterDescriptors.Remove("MesName");
                    this.gridEquipments.FilterDescriptors.Remove("EquipmentID");

                    if (string.IsNullOrWhiteSpace(this.tboxEquipmentID.Text) == false)
                    {
                        Telerik.WinControls.Data.FilterDescriptor filter = new Telerik.WinControls.Data.FilterDescriptor("EquipmentID", Telerik.WinControls.Data.FilterOperator.Contains, this.tboxEquipmentID.Text);
                        this.gridEquipments.FilterDescriptors.Add(filter);
                    }
                    if (string.IsNullOrWhiteSpace(this.tboxName.Text) == false)
                    {
                        string columnName = string.Empty; ;
                        if (string.IsNullOrEmpty(columnName)) columnName = this.gridEquipments.Columns["DisplayName"].IsVisible ? "DisplayName" : string.Empty;
                        if (string.IsNullOrEmpty(columnName)) columnName = this.gridEquipments.Columns["MesName"].IsVisible ? "MesName" : string.Empty;
                        if (string.IsNullOrEmpty(columnName)) columnName = "DisplayName";

                        Telerik.WinControls.Data.FilterDescriptor filter = new Telerik.WinControls.Data.FilterDescriptor(columnName, Telerik.WinControls.Data.FilterOperator.Contains, this.tboxName.Text);
                        this.gridEquipments.FilterDescriptors.Add(filter);
                    }
                    break;
                case Keys.Escape:
                    if (sender == this.tboxEquipmentID) this.gridEquipments.FilterDescriptors.Remove("EquipmentID");
                    if (sender == this.tboxName) { this.gridEquipments.FilterDescriptors.Remove("DisplayName"); this.gridEquipments.FilterDescriptors.Remove("MesName"); }
                    break;
            }
        }

        private void ChkAllEquipment_CheckStateChanged(object sender, EventArgs e)
        {
            this.CboxServer_SelectedValueChanged(this.cboxServer, null);
            GlobalVariable.Instance.FrmEqSelector_AllEquipment = this.chkAllEquipment.Checked;
        }

        #endregion

        #region [ GridEquipments ] --------------------------------------------

        private void GridEquipments_Setting()
        {
            GridViewEx grid = this.gridEquipments;
            grid.TableElement.RowHeight = 20;
            grid.MultiSelect = true;

            Dictionary<string, string> dicColumnText = new Dictionary<string, string>();
            dicColumnText.Add("Facility", "");
            dicColumnText.Add("Line", "");
            dicColumnText.Add("EquipmentID", "");
            dicColumnText.Add("DisplayName", "Name");
            dicColumnText.Add("ProcessSegmentID", "공정ID");
            dicColumnText.Add("ProcessSegmentName", "공정명");
            dicColumnText.Add("MesName", "MES Name");
            dicColumnText.Add("Description", "EIS Name");
            dicColumnText.Add("ControlMode", "Control");
            dicColumnText.Add("State", "");
            dicColumnText.Add("LastTrackInLotID", "In LOT");
            dicColumnText.Add("LastTrackOutLotID", "Out LOT");
            dicColumnText.Add("ModelID", "");
            dicColumnText.Add("Maker", "");
            dicColumnText.Add("Version", "");
            dicColumnText.Add("ModelVersion", "ModelVer");
            dicColumnText.Add("EquipmentIP", "");
            dicColumnText.Add("Port", "");
            dicColumnText.Add("ServerIP", "");
            dicColumnText.Add("OriginServerIP", "OriginIP");
            dicColumnText.Add("GemSettingID", "GemID");
            dicColumnText.Add("DriverFileName", "Driver File");
            dicColumnText.Add("LogPath", "");
            dicColumnText.Add("PMDate", "PM Date");
            dicColumnText.Add("PlcType", "PLC Type");

            #region [저장된 컬럼순서 적용]
            string columnNames = GlobalVariable.Instance.FrmEqSelector_GridEquipmentHeader;
            string columnText = string.Empty;
            if (string.IsNullOrEmpty(columnNames) == false)
            {
                foreach (string columnName in columnNames.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries))
                {
                    columnText = columnName;
                    if (dicColumnText.ContainsKey(columnName))
                    {
                        if (string.IsNullOrEmpty(dicColumnText[columnName]) == false) columnText = dicColumnText[columnName];
                        dicColumnText.Remove(columnName);
                    }

                    grid.AddColumn(columnName, columnText);
                }
            }

            foreach (string columnName in dicColumnText.Keys)
            {
                columnText = columnName;
                if (string.IsNullOrEmpty(dicColumnText[columnName]) == false) columnText = dicColumnText[columnName];
                grid.AddColumn(columnName, columnText).IsVisible = false;
            }
            #endregion

            grid.AddContextMenu("");
            grid.AddContextMenu("Open Windows", this.GridEquipments_OpenWindows);
        }

        /// <summary>
        /// [CheckPoint] 선택된 설비의 로그파일 목록을 표시한다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GridEquipments_SelectionChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.gridEquipments.SelectedRows.Count < 1) return;
                this.gridLogFiles.DataSource = null;
                this.gridModelDetail.DataSource = null;
                this.gridWorkflow.DataSource = null;
                this.gridHsms.DataSource = null;
                //if (this.tabControl1.TabPages.Contains(this.tabHSMS)) this.tabControl1.TabPages.Remove(this.tabHSMS);

                EisEquipment equipment = this.gridEquipments.SelectedRows[0].DataBoundItem as EisEquipment;
                if (equipment == null) return;

                this.Cursor = Cursors.WaitCursor;
                this.Equipment = equipment;
                LogServer logServer = this.cboxServer.SelectedItem as LogServer;
                string path = string.Empty;

                #region [ Model Details ]

                // 모델 버전 정보
                EisModelDetails[] modelDetails = this.GetModelDetails(equipment);
                this.gridModelDetail.AutoBinding(modelDetails);
                this.gridModelDetail.SetRowForeColor("LockState", $"LockState = 'BLOCKED'", Color.LightGray);
                foreach (GridViewRowInfo row in this.gridModelDetail.Rows)
                {
                    EisModelDetails item = row.DataBoundItem as EisModelDetails;
                    if (item == null) continue;
                    if (item.Version == equipment.Version)
                    {
                        row.IsSelected = true;
                        row.IsCurrent = true;
                        break;
                    }
                }

                // 모델 정보
                EisModelInfo[] modelInfo = this.GetModelInfo(equipment);
                if (modelInfo?.Length > 0)
                {
                    this.tboxModelDescription.Text = modelInfo[0].Description;
                }

                #endregion

                #region [ LogFiles ]

                if (logServer.NetworkAccount.ContainsKey(equipment.LogServerIP) == false) return;
                {
                    this.Account = logServer.NetworkAccount[equipment.LogServerIP];
                    switch (this.Account.Access)
                    {
                        case AccessType.SMB:
                            {
                                // Checking Local IP-Address
                                bool isLocal = false;
                                foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
                                    foreach (UnicastIPAddressInformation ip in nic.GetIPProperties().UnicastAddresses)
                                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                                            if (ip.Address.ToString() == this.Account.IPAddress) { isLocal = true; break; }

                                if (this.chkUseSMB.Checked)
                                {
                                    if (isLocal) path = $@"{equipment.LogPath}\{equipment.EquipmentID}";
                                    else return;
                                }
                                else
                                {
                                    if (isLocal) path = $@"{equipment.LogPath}\{equipment.EquipmentID}";
                                    else path = $@"\\{this.Account.IPAddress}\{this.Account.DefaultPath}{equipment.EquipmentID}\";
                                }

                                int result = ExtensionAPI.ConnectRemoteServer(this.Account.IPAddress, this.Account.UserID, this.Account.Password);
                                if (result != 0 && result != 1219) { MessageBox.Show($@"네트워크 접근에 실패하였습니다. (Code:{result})"); return; }

                                DirectoryInfo directory = new DirectoryInfo(path);
                                if (directory.Exists == false) { MessageBox.Show($@"폴더가 존재하지 않습니다" + Environment.NewLine + Environment.NewLine + $@"Path: {path}"); return; }

                                this.gridLogFiles.AutoBinding(this.GetLogFiles(directory.GetFiles()));
                                this.rstatus1.Text = $"Path={path}";
                            }
                            break;
                        case AccessType.FTPS:
                            {
                                FtpsClient.Initialize(this.Account.IPAddress, this.Account.UserID, this.Account.Password);
                                FtpsClient.Connect();

                                path = $"/{this.Account.DefaultPath}/{equipment.EquipmentID}";
                                FtpListItem[] ftpFiles = FtpsClient.GetFtpsList(path);
                                if (ftpFiles != null) this.gridLogFiles.AutoBinding(this.GetLogFiles(ftpFiles));
                                this.rstatus1.Text = $"Path={this.Account.IPAddress}{path}";

                                //if (FtpsClient.IsDirExists($"{path}/THiRA_SECSGEM/HSMS") && !this.tabControl1.TabPages.Contains(tabHSMS))
                                //    this.tabControl1.TabPages.Add(this.tabHSMS);

                                FtpsClient.Disconnect();
                            }
                            break;
                        case AccessType.SFTP:
                            {
                                StpClientWrap.Initialize(this.Account.IPAddress, this.Account.UserID, this.Account.Password);
                                StpClientWrap.Connect();

                                path = $"/{this.Account.DefaultPath}/{equipment.EquipmentID}";
                                ISftpFile[] ftpFiles = (ISftpFile[])StpClientWrap.GetSftpList(path);
                                if (ftpFiles != null) this.gridLogFiles.AutoBinding(this.GetLogFiles(ftpFiles));
                                this.rstatus1.Text = $"Path={this.Account.IPAddress}{path}";

                                //if (StpClientWrap.IsDirExists($"{path}/THiRA_SECSGEM/HSMS") && !this.tabControl1.TabPages.Contains(tabHSMS))
                                //    this.tabControl1.TabPages.Add(this.tabHSMS);

                                StpClientWrap.Disconnect();
                            }
                            break;
                        case AccessType.FTP:
                            {

                            }
                            break;
                    }
                }

                #endregion

                #region [ Workflow & HSMS ]

                this.tabControl1_SelectedIndexChanged(this.tabControl1, new EventArgs());

                #endregion

            }
            catch (Exception ex)
            {
                if (this.LogServer.NetworkAccount.ContainsKey(this.Equipment.LogServerIP))
                {
                    // 해당 접속정보를 삭제한다
                    this.LogServer.NetworkAccount.Remove(this.Equipment.LogServerIP);
                    ExpressionFormattingObject formatting = new ExpressionFormattingObject($"Marking", $"ServerIP = '{this.Equipment.LogServerIP}'", true);
                    formatting.RowBackColor = Color.FromArgb(88, 255, 0, 0);
                    this.gridEquipments.Columns["ServerIP"].ConditionalFormattingObjectList.Add(formatting);
                }
                XLogger.Instance.Fatal(ex, true);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// [CheckPoint] 선택된 설비의 로그파일 목록을 표시한다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void xGridEquipments_SelectionChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.gridEquipments.SelectedRows.Count < 1) return;
                this.gridLogFiles.DataSource = null;
                this.gridModelDetail.DataSource = null;

                EisEquipment equipment = this.gridEquipments.SelectedRows[0].DataBoundItem as EisEquipment;
                if (equipment == null) return;

                this.Cursor = Cursors.WaitCursor;
                this.Equipment = equipment;
                LogServer logServer = this.cboxServer.SelectedItem as LogServer;
                string path = string.Empty;

                #region [ Model Details ]
                // 모델 버전 정보
                EisModelDetails[] modelDetails = this.GetModelDetails(equipment);
                this.gridModelDetail.AutoBinding(modelDetails);
                this.gridModelDetail.SetRowForeColor("LockState", $"LockState = 'BLOCKED'", Color.LightGray);
                foreach (GridViewRowInfo row in this.gridModelDetail.Rows)
                {
                    EisModelDetails item = row.DataBoundItem as EisModelDetails;
                    if (item == null) continue;
                    if (item.Version == equipment.Version)
                    {
                        row.IsSelected = true;
                        row.IsCurrent = true;
                        break;
                    }
                }

                // 모델 정보
                EisModelInfo[] modelInfo = this.GetModelInfo(equipment);
                if (modelInfo?.Length > 0)
                {
                    this.tboxModelDescription.Text = modelInfo[0].Description;
                }
                #endregion

                #region [ LogFiles ]
                if (logServer.NetworkAccount.ContainsKey(equipment.LogServerIP)) //jhlim 20250202 jj
                {
                    // Checking Local IP-Address
                    foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
                    {
                        foreach (UnicastIPAddressInformation ip in nic.GetIPProperties().UnicastAddresses)
                        {
                            if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                            {
                                if (ip.Address.ToString() == equipment.LogServerIP)
                                {
                                    path = $@"{equipment.LogPath}\{equipment.EquipmentID}";
                                    break;
                                }
                            }
                        }
                    }

                    // SMB (Server Message Block)
                    //if (string.IsNullOrEmpty(path) && this.chkUseSMB.Checked)
                    //{
                    //    Account account = logServer.NetworkAccount[equipment.LogServerIP];
                    //    int result = ExtensionAPI.ConnectRemoteServer(account.IPAddress, account.UserID, account.Password);
                    //    if (result != 0 && result != 1219) { MessageBox.Show($@"네트워크 접근에 실패하였습니다. (Code:{result})"); return; }
                    //    path = logServer.GetLogPath(equipment.LogServerIP, equipment.EquipmentID);
                    //}

                    if (string.IsNullOrEmpty(path) && this.chkUseSMB.Checked)  //jhlim 20250202
                    {
                        Account account = logServer.NetworkAccount[equipment.LogServerIP];
                        object rtnObj = null;

                        // StpClientWrap 사용
                        //StpClientWrap.Initialize(equipment?.LogServerIP, "test", "daeduck!1");
                        //StpClientWrap.Connect();
                        var svrInfo = (DDUtilityApp.DATA.Account)GetNetworkAccount(equipment?.LogServerIP);
                        FtpsClient.Initialize(equipment?.LogServerIP, svrInfo.UserID, svrInfo.Password);
                        FtpsClient.Connect();

                        var remotePath = $"/{svrInfo.DefaultPath}/{equipment.EquipmentID}";
                        //var remotePath = $"{equipment.EquipmentID}";
                        // SFTP 파일 목록 가져오기
                        //rtnObj = StpClientWrap.GetSftpList(remotePath);
                        rtnObj = FtpsClient.GetFtpsList(remotePath);

                        if (rtnObj == null) return;
                        //StpClientWrap.IsDirectory( "/302304/THiRA_SECSGEM/HSMS")
                        //var hsmsEnabled = (StpClientWrap.IsDirExists( $"{remotePath}/THiRA_SECSGEM/HSMS"));
                        var hsmsEnabled = (FtpsClient.IsDirExists($"{remotePath}/THiRA_SECSGEM/HSMS"));

                        if (hsmsEnabled == false)
                        {
                            if (tabControl1.TabPages.Contains(tabHSMS))
                            {
                                tabControl1.TabPages.Remove(tabHSMS);
                            }
                        }
                        else
                        {
                            if (!tabControl1.TabPages.Contains(tabHSMS))
                            {
                                tabControl1.TabPages.Add(tabHSMS);
                            }
                        }

                        this.gridLogFiles.AutoBinding(GetFtpslogFiles(rtnObj));

                        // 연결 종료 //jhlim 20250202
                        //StpClientWrap.Disconnect();
                        FtpsClient.Disconnect();
                    }
                    else if (string.IsNullOrEmpty(path) == false)
                    {
                        // 로그 파일 목록
                        DirectoryInfo directory = new DirectoryInfo(path);
                        if (directory.Exists == false)
                        {
                            MessageBox.Show($@"폴더가 존재하지 않습니다" + Environment.NewLine + Environment.NewLine + $@"Path: {path}");
                            return;
                        }
                        LogFile[] logFiles = directory.GetFiles().ToClass<LogFile>().OrderByDescending(x => x.Name).ToArray();
                        this.gridLogFiles.AutoBinding(logFiles);
                    }
                }
                else
                {
                    path = $@"{equipment.LogPath}\{equipment.EquipmentID}";
                }
                this.rstatus1.Text = path;
                if (string.IsNullOrEmpty(path)) return;
                #endregion

                //// 로그 파일 목록
                //DirectoryInfo directory = new DirectoryInfo(path);
                //if (directory.Exists == false)
                //{
                //    MessageBox.Show($@"폴더가 존재하지 않습니다" + Environment.NewLine + Environment.NewLine + $@"Path: {path}");
                //    return;
                //}
                //LogFile[] logFiles = directory.GetFiles().ToClass<LogFile>().OrderByDescending(x => x.Name).ToArray();
                //this.gridLogFiles.AutoBinding(logFiles);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex, true);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void GridEquipments_CellDoubleClick(object sender, GridViewCellEventArgs e)
        {
            try
            {
                this.gridLogFiles.ClearSelection();
                if (this.gridLogFiles.Rows.Count > 0) this.gridLogFiles.Rows[0].IsSelected = true;
                this.GridLogFiles_CellDoubleClick(this.gridLogFiles, null);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        private void GridEquipments_DataBindingComplete(object sender, GridViewBindingCompleteEventArgs e)
        {
            GridViewEx grid = this.gridEquipments;
            if (grid.Columns.Contains("Version"))
            {
                bool isExist = false;
                foreach (BaseFormattingObject item in grid.Columns["Version"].ConditionalFormattingObjectList)
                    if (item.Name == "VERSION_MissMatch") isExist = true;
                if (isExist == false)
                {
                    ExpressionFormattingObject formatting = new ExpressionFormattingObject($"VERSION_MissMatch", "Version<>ModelVersion", true);
                    formatting.CellBackColor = Color.FromArgb(128, 255, 0, 0);
                    grid.Columns["Version"].ConditionalFormattingObjectList.Add(formatting);
                }
            }
            if (grid.Columns.Contains("PMDate"))
            {
                bool isExist = false;
                foreach (BaseFormattingObject item in grid.Columns["PMDate"].ConditionalFormattingObjectList)
                    if (item.Name == "PMDate_MissMatch") isExist = true;
                if (isExist == false)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.Append($"PMDate>=#{DateTime.Now.ToString("yyyy-MM-dd")}#");
                    sb.Append(" AND ");
                    sb.Append($"PMDate<#{DateTime.Now.AddDays(1).ToString("yyyy-MM-dd")}#");
                    ExpressionFormattingObject formatting = new ExpressionFormattingObject($"PMDate_MissMatch", sb.ToString(), true);
                    formatting.CellBackColor = Color.YellowGreen;
                    grid.Columns["PMDate"].ConditionalFormattingObjectList.Add(formatting);
                }
            }
        }

        private void GridEquipments_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) this.BtnOK_Click(this.btnOK, null);
        }

        private void GridEquipments_OpenWindows(object sender, params object[] args)
        {
            try
            {
                if (this.gridEquipments.SelectedRows.Count < 1) return;
                string serverID = this.cboxServer.Text;
                string equipmentID = this.gridEquipments.SelectedRows[0].Cells["EquipmentID"].Value.ToString();
                //this.gridLogFiles.SelectedRows;

                ProcessStartInfo processStartInfo = new ProcessStartInfo();
                processStartInfo.FileName = Application.ExecutablePath;
                processStartInfo.WorkingDirectory = Environment.CurrentDirectory;
                processStartInfo.Arguments = $"FrmLogParser {serverID} {equipmentID}";
                Process process = Process.Start(processStartInfo);

                //this.DialogResult = DialogResult.Cancel;
                //this.Close();
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        #endregion

        #region [ GridLogFiles ] ----------------------------------------------

        private void GridLogFiles_Setting(GridViewEx grid)
        {
            //GridViewEx grid = this.gridLogFiles;  jhlim 20250202
            grid.TableElement.RowHeight = 20;
            grid.MultiSelect = true;

            grid.AddColumn("Name");
            grid.AddColumn("Length");
            grid.AddColumn("LastWriteTime");

            //grid.AddContextMenu("");
            //grid.AddContextMenu("Open Log", GridEquipments_OpenWindows);
        }

        private void GridLogFiles_CellDoubleClick(object sender, GridViewCellEventArgs e)
        {
            try
            {
                this.BtnOK_Click(this.btnOK, null);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex, true);
            }
        }

        private void GridLogFiles_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) this.BtnOK_Click(this.btnOK, null);
        }

        #endregion

        #region [ Grid Worflow & HSMS ] ----------------------------------------------

        /// <summary>
        /// Workflow, HSMS 파일목록 Grid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Grid_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                Grid_CellDoubleClick((GridViewEx)sender, null);
            }
        }

        /// <summary>
        /// Workflow, HSMS 파일 Download
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Grid_CellDoubleClick(object sender, GridViewCellEventArgs e)
        {
            try
            {
                string destPath = Path.Combine(GlobalVariable.Instance.DownloadPath, this.Equipment.EquipmentID);

                RadGridView grid = sender as RadGridView;
                if (grid == null && sender.GetType() == typeof(GridDataCellElement))
                {
                    GridDataCellElement element = sender as GridDataCellElement;
                    grid = element.RowElement.GridControl;
                }
                if (grid == null) return;

                if (grid == this.gridHsms) destPath = Path.Combine(destPath, "HSMS");
                else if (grid == this.gridWorkflow) destPath = Path.Combine(destPath, "Workflow");
                if (System.IO.Directory.Exists(destPath) == false) System.IO.Directory.CreateDirectory(destPath);

                List<string> downfiles = new List<string>();
                foreach (GridViewRowInfo row in grid.SelectedRows)
                {
                    LogFile logFile = row.DataBoundItem as LogFile;
                    string destFileName = Path.Combine(destPath, logFile.FileName);

                    switch (this.Account.Access)
                    {
                        case AccessType.SMB:
                            { }
                            break;
                        case AccessType.FTPS:
                            {
                                FtpsClient.DownloadFtpsFile(logFile.FullName, destFileName);
                                downfiles.Add(destFileName);
                                logFile.DestFullName = destFileName;
                            }
                            break;
                        case AccessType.SFTP:
                            {
                                StpClientWrap.DownloadSftpFile(logFile.FullName, destFileName);
                                downfiles.Add(destFileName);
                                logFile.DestFullName = destFileName;
                            }
                            break;
                        case AccessType.FTP:
                            { }
                            break;
                    }
                }

                MessageBox.Show($"{grid.SelectedRows.Count}개의 파일을 저장하였습니다.");
                foreach (string file in downfiles)
                    System.Diagnostics.Process.Start(file);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex, true);
            }
        }

        private void GridLogFiles_OpenWindows(object sender, params object[] args)
        {
            try
            {
                if (this.gridEquipments.SelectedRows.Count < 1) return;
                string serverID = this.cboxServer.Text;
                string equipmentID = this.gridEquipments.SelectedRows[0].Cells["EquipmentID"].Value.ToString();

                ProcessStartInfo processStartInfo = new ProcessStartInfo();
                processStartInfo.FileName = Application.ExecutablePath;
                processStartInfo.WorkingDirectory = Environment.CurrentDirectory;
                processStartInfo.Arguments = $"FrmLogParser {serverID} {equipmentID}";
                Process process = Process.Start(processStartInfo);

                //this.DialogResult = DialogResult.Cancel;
                //this.Close();
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        #endregion

        #region [ GridModelDetail ] -------------------------------------------

        private void GridModelDetail_Setting()
        {
            GridViewDataColumn item = null;
            GridViewEx grid = this.gridModelDetail;
            grid.MasterView.TableHeaderRow.MinHeight = 30;
            grid.AutoSizeRows = true;
            //grid.AllowDragToGroup = false;
            grid.AllowAutoSizeColumns = false;
            //grid.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;

            grid.Columns.Clear();
            grid.AddColumn("ModelID").IsVisible = false;
            item = grid.AddColumn("Version");
            item.MinWidth = 100; item.MaxWidth = 120;
            item = grid.AddColumn("Description");
            item.MinWidth = 100; //item.MaxWidth = 500;
            item = grid.AddColumn("DateTime");
            item.MinWidth = 100; item.MaxWidth = 130;
            item = grid.AddColumn("Modifier");
            item.MinWidth = 80; item.MaxWidth = 80;
            //grid.AddColumn("LockState");
        }

        private EisModelDetails[] GetModelDetails(EisEquipment equipment)
        {
            try
            {

                LogServer logServer = this.cboxServer.SelectedItem as LogServer;
                if (logServer == null) return null;
                this.LogServer = logServer;

                this.Cursor = Cursors.WaitCursor;
                DataTable dtModelDetails = logServer.GetModelDetails(equipment.ModelID);
                EisModelDetails[] modelDetails = dtModelDetails.ToClass<EisModelDetails>();

                return modelDetails;
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex, true);
                return null;
            }
        }

        private EisModelInfo[] GetModelInfo(EisEquipment equipment)
        {
            try
            {
                LogServer logServer = this.cboxServer.SelectedItem as LogServer;
                if (logServer == null) return null;
                this.LogServer = logServer;

                this.Cursor = Cursors.WaitCursor;
                DataTable dtModelDetails = logServer.GetModelInfo(equipment.ModelID);
                EisModelInfo[] modelDetails = dtModelDetails.ToClass<EisModelInfo>();

                return modelDetails;
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex, true);
                return null;
            }
        }

        #endregion

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

        private void SetLogServer()
        {
            this.cboxServer.Items.Clear();
            StringBuilder sbEquipments = new StringBuilder();
            StringBuilder sbModelDetails = new StringBuilder();
            StringBuilder sbModelInfo = new StringBuilder();

            LogServer logServer = null;
            switch (this.ServerType)
            {
                case eServerType.EIS:
                    sbEquipments.Clear();
                    sbEquipments.AppendLine($"SELECT  EQ.Line, ");
                    sbEquipments.AppendLine($"        EQ.ModelID, ");
                    sbEquipments.AppendLine($"        (SELECT MAX(Version) FROM EquipmentModelDetails WHERE ModelID=EQ.ModelID AND LockState != 'BLOCKED') ModelVersion, ");
                    sbEquipments.AppendLine($"        EQ.Version, ");
                    sbEquipments.AppendLine($"        EQ.RunningVersion, ");
                    sbEquipments.AppendLine($"        EQ.EquipmentID, ");
                    sbEquipments.AppendLine($"        EQ.Description, ");
                    sbEquipments.AppendLine($"        DP.GemSettingID, ");
                    sbEquipments.AppendLine($"        DP.DriverFileName, ");
                    sbEquipments.AppendLine($"        DP.EquipmentIP, ");
                    sbEquipments.AppendLine($"        DP.Port, ");
                    sbEquipments.AppendLine($"        EQ.ServerIP, ");
                    sbEquipments.AppendLine($"        EQ.OriginServerIP, ");
                    sbEquipments.AppendLine($"        DP.MESDaemon, ");
                    sbEquipments.AppendLine($"        DP.MESService, ");
                    sbEquipments.AppendLine($"        DP.MESSubject, ");
                    sbEquipments.AppendLine($"        DP.PlcType, ");
                    sbEquipments.AppendLine($"        EQ.LogPath ");
                    sbEquipments.AppendLine($"FROM    Equipment EQ ");
                    sbEquipments.AppendLine($"        LEFT JOIN ( ");
                    sbEquipments.AppendLine($"            SELECT  DP1.EquipmentID, ");
                    sbEquipments.AppendLine($"                    DP1.GemSettingID, ");
                    sbEquipments.AppendLine($"                    DP1.Value EquipmentIP, ");
                    sbEquipments.AppendLine($"                    DP2.Value DriverFileName, ");
                    sbEquipments.AppendLine($"                    DP3.Value Port, ");
                    sbEquipments.AppendLine($"                    DP4.Value MESDaemon, ");
                    sbEquipments.AppendLine($"                    DP5.Value MESService, ");
                    sbEquipments.AppendLine($"                    DP6.Value MESSubject, ");
                    sbEquipments.AppendLine($"                    DP7.Value PlcType ");
                    sbEquipments.AppendLine($"            FROM    DriverParameter DP1 ");
                    sbEquipments.AppendLine($"                    LEFT JOIN DriverParameter DP2 ON DP2.EquipmentID=DP1.EquipmentID AND DP2.DriverName=DP1.DriverName AND DP2.Name IN ('MessageFileName', 'PLC_MAPFILENAME') ");
                    sbEquipments.AppendLine($"                    LEFT JOIN DriverParameter DP3 ON DP3.EquipmentID=DP1.EquipmentID AND DP3.DriverName=DP1.DriverName AND DP3.Name IN ('PortNo', 'PLC_PORT') ");
                    sbEquipments.AppendLine($"                    LEFT JOIN DriverParameter DP4 ON DP4.EquipmentID=DP1.EquipmentID AND DP4.DriverName='MES' AND DP4.Name IN ('Daemon') ");
                    sbEquipments.AppendLine($"                    LEFT JOIN DriverParameter DP5 ON DP5.EquipmentID=DP1.EquipmentID AND DP5.DriverName='MES' AND DP5.Name IN ('Service') ");
                    sbEquipments.AppendLine($"                    LEFT JOIN DriverParameter DP6 ON DP6.EquipmentID=DP1.EquipmentID AND DP6.DriverName='MES' AND DP6.Name IN ('SendSubject') ");
                    sbEquipments.AppendLine($"                    LEFT JOIN DriverParameter DP7 ON DP7.EquipmentID=DP1.EquipmentID AND DP7.DriverName='EQP' AND DP7.Name IN ('PLC_TYPE') ");
                    sbEquipments.AppendLine($"            WHERE   DP1.Name IN ('RemoteAddress', 'PLC_IPADDRESS') ) DP ON DP.EquipmentID = EQ.EquipmentID ");
                    sbEquipments.AppendLine($"ORDER BY Line, ModelID, EquipmentID ");

                    sbModelDetails.Clear();
                    sbModelDetails.AppendLine($"SELECT  * ");
                    sbModelDetails.AppendLine($"FROM    EquipmentModelDetails ");
                    sbModelDetails.AppendLine($"WHERE   ModelID=@MODEL_ID ");
                    sbModelDetails.AppendLine($"ORDER BY Version DESC ");

                    sbModelInfo.Clear();
                    sbModelInfo.AppendLine($"SELECT  * ");
                    sbModelInfo.AppendLine($"FROM    EquipmentModel ");
                    sbModelInfo.AppendLine($"WHERE   ModelID=@MODEL_ID ");

                    #region [ EIS.B1 ]
                    logServer = new LogServer("EIS.B1");
                    logServer.DBConnectionString = $@"server=192.168.7.208;database=DDEIS;uid=EES_Service;pwd=99dU6QABcghnV^;";
                    logServer.DBGetEquipments = sbEquipments.ToString();
                    logServer.DBGetModelDetails = sbModelDetails.ToString();
                    logServer.DBGetModelInfo = sbModelInfo.ToString();

                    // B1
                    logServer.NetworkAccount.Add("192.168.7.214", new Account("192.168.7.214", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.7.215", new Account("192.168.7.215", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.7.216", new Account("192.168.7.216", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.7.217", new Account("192.168.7.217", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.7.218", new Account("192.168.7.218", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.7.219", new Account("192.168.7.219", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    //logServer.NetworkAccount.Add("192.168.7.150", new Account("192.168.7.150", "T001084@DAEDUCK.COM", "daeduck!1", @"Vol2\EIS서버\"));

                    // B1 (Multi-NIC)
                    logServer.NetworkAccount.Add("192.168.115.214", new Account("192.168.7.214", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.115.215", new Account("192.168.7.215", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.115.216", new Account("192.168.7.216", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.115.217", new Account("192.168.7.217", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.115.218", new Account("192.168.7.218", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.115.219", new Account("192.168.7.219", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.235.214", new Account("192.168.7.214", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.235.215", new Account("192.168.7.215", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.235.216", new Account("192.168.7.216", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.235.217", new Account("192.168.7.217", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.235.218", new Account("192.168.7.218", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.235.219", new Account("192.168.7.219", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));

                    // B1.PLC
                    logServer.NetworkAccount.Add("192.168.113.231", new Account("192.168.113.231", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.113.232", new Account("192.168.113.232", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.113.233", new Account("192.168.113.233", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.113.236", new Account("192.168.113.236", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.233.231", new Account("192.168.233.231", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.233.232", new Account("192.168.233.232", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.233.233", new Account("192.168.233.233", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));

                    // M1
                    logServer.NetworkAccount.Add("192.168.143.231", new Account("192.168.143.231", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.143.232", new Account("192.168.143.232", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.143.233", new Account("192.168.143.233", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.143.235", new Account("192.168.143.235", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));

                    logServer.FTPAddress = "192.168.7.208";
                    logServer.FTPPort = 7000;
                    logServer.FTPUserID = "anonymous";
                    logServer.FTPPassword = "";
                    //logServer.FTPUserID = "EES_Service";
                    //logServer.FTPPassword = "99dU6QABcghnV^";
                    this.cboxServer.Items.Add(logServer);
                    #endregion

                    #region [ EIS.B2 ]
                    logServer = new LogServer("EIS.B2");
                    logServer.DBConnectionString = $@"server=192.168.8.217;database=EIS;uid=EIS_Service;pwd=Yi^d!3dqpc%m;";
                    logServer.DBGetEquipments = sbEquipments.ToString();
                    logServer.DBGetModelDetails = sbModelDetails.ToString();
                    logServer.DBGetModelInfo = sbModelInfo.ToString();
                    logServer.NetworkAccount.Add("192.168.8.215", new Account("192.168.8.215", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.8.216", new Account("192.168.8.216", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.NetworkAccount.Add("192.168.8.217", new Account("192.168.8.217", "loguser", "Daeduck!1", @"EISLog", AccessType.FTPS));
                    logServer.FTPAddress = "192.168.8.217";
                    logServer.FTPPort = 21;
                    logServer.FTPUserID = "anonymous";
                    logServer.FTPPassword = "";
                    this.cboxServer.Items.Add(logServer);
                    #endregion

                    break;
                case eServerType.AGV:
                    break;
            }
        }

        public EisEquipment[] GetEquipments()
        {
            try
            {
                LogServer logServer = this.cboxServer.SelectedItem as LogServer;
                if (logServer == null) return null;
                this.LogServer = logServer;

                this.Cursor = Cursors.WaitCursor;
                DataTable dtEisEquipment = logServer.GetEquipments();
                EisEquipment[] equipments = dtEisEquipment.ToClass<EisEquipment>();

                // Get Equipment Information of the MES Database
                DataTable dtMesEquipment = this.GetMesEquipment();
                foreach (EisEquipment equipment in equipments)
                {
                    equipment.DisplayNameOrder = GlobalVariable.Instance.FrmEqSelector_NameOrder;
                    equipment.Server = logServer;
                    equipment.Description = equipment.Description.Replace("EQP_NAME=", "");

                    #region [ Setting Equipment Information with MES ]
                    try
                    {
                        if (dtMesEquipment != null)
                        {
                            DataRow[] mesRows = dtMesEquipment.Select($"EQUIPMENTID='{equipment.EquipmentID}'");
                            equipment.MesRegistration = false;
                            if (mesRows.Length < 1) continue;

                            DataRow row = mesRows[0];
                            if (mesRows.Length > 0)
                            {
                                for (int i = 0; i < mesRows.Length; i++)
                                {
                                    if (mesRows[i]["SITEID"].ToString() == "1130")
                                    {
                                        row = mesRows[i];
                                        break;
                                    }
                                }
                            }

                            equipment.Facility = row["FACILITYNAME"].ToString();
                            equipment.ProcessSegmentID = row["PROCESSSEGMENTID"].ToString();
                            equipment.ProcessSegmentName = row["PROCESSSEGMENTNAME"].ToString();
                            equipment.MesName = row["DESCRIPTION"].ToString();
                            equipment.OperationMode = row["OPERATIONMODE"].ToString();
                            equipment.ControlMode = row["CONTROLMODE"].ToString();
                            equipment.State = row["EQPSTATE"].ToString();
                            equipment.LastTrackInLotID = row["LASTTRACKINLOTID"].ToString();
                            equipment.LastTrackOutLotID = row["LASTTRACKOUTLOTID"].ToString();
                            equipment.Maker = row["MAKER"].ToString();
                            DateTime pmDateTime = DateTime.MinValue;
                            if (DateTime.TryParseExact(row["PLANDATE"].ToString(), "yyyyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out pmDateTime))
                                equipment.PMDate = pmDateTime;
                            equipment.MesRegistration = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        XLogger.Instance.Fatal(ex);
                    }
                    #endregion

                }

                return equipments.OrderBy(x => x.OrderByKey).ThenBy(x => x.Line).ThenBy(x => x.ProcessSegmentID).ThenBy(x => x.MesName).ToArray();
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex, true);
                return null;
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void SetEquipment(DataTableBase equipment)
        {
            try
            {
                if (equipment == null) return;

                EisEquipment eqp = equipment as EisEquipment;
                if (eqp != null)
                {
                    if (eqp.Server == null) return;
                    foreach (LogServer server in this.cboxServer.Items)
                    {
                        if (server.Name == eqp.Server.Name)
                        {
                            this.cboxServer.SelectedItem = server;
                            foreach (GridViewRowInfo row in this.gridEquipments.Rows)
                            {
                                EisEquipment bindItem = row.DataBoundItem as EisEquipment;
                                if (bindItem == null) continue;
                                if (bindItem.EquipmentID == eqp.EquipmentID)
                                {
                                    row.IsSelected = true;
                                    row.IsCurrent = true;
                                }
                            }
                        }
                    }
                    return;
                }
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        private void SetEquipment(string serverName, string equipmentID)
        {
            try
            {
                foreach (LogServer server in this.cboxServer.Items)
                {
                    if (server.Name == serverName)
                    {
                        this.cboxServer.SelectedItem = server;
                        foreach (GridViewRowInfo row in this.gridEquipments.Rows)
                        {
                            EisEquipment bindItem = row.DataBoundItem as EisEquipment;
                            if (bindItem == null) continue;
                            if (bindItem.EquipmentID == equipmentID)
                            {
                                row.IsSelected = true;
                                row.IsCurrent = true;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        private void SetSelectedLogFiles(LogFile[] logFiles)
        {
            this.gridLogFiles.ClearSelection();

            GridViewRowInfo current = null;
            foreach (GridViewRowInfo row in this.gridLogFiles.Rows)
            {
                LogFile item = row.DataBoundItem as LogFile;
                if (item == null) continue;

                foreach (LogFile logFile in logFiles)
                {
                    if (string.Compare(item.FileName, logFile.FileName, true) == 0)
                    {
                        if (current == null)
                        {
                            current = row;
                            row.IsCurrent = true;
                        }
                        row.IsSelected = true;
                        break;
                    }
                }
            }
        }

        private object GetNetworkAccount(string logserverIP) //jhim 20250202
        {
            return ((LogServer)this.cboxServer.SelectedItem)?.NetworkAccount[logserverIP];
        }

        /// <summary>
        /// DB에서 GEM 정보 수집
        /// </summary>
        private void GetGEMSetting()
        {
            try
            {
                LogServer logServer = this.cboxServer.SelectedItem as LogServer;
                if (logServer == null) return;
                if (this.Equipment == null) return;

                this.Cursor = Cursors.WaitCursor;
                DataSet ds = logServer.ExecuteQuery($"SELECT GEMObject FROM GEMParameter WHERE ModelID='{this.Equipment.ModelID}' AND GemSettingID='{this.Equipment.GemSettingID}'");
                if (ds == null || ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 1) return;

                byte[] byteObject = (byte[])ds.Tables[0].Rows[0][0];
                EIS.Framework.Service.GEM.GEMSettings gem = byteObject.ToObject<EIS.Framework.Service.GEM.GEMSettings>();

                this.SECSDefine = new SECSDefine(gem);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex, true);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// MES DB에서 설비정보 수집
        /// </summary>
        /// <returns></returns>
        private DataTable GetMesEquipment()
        {
            SqlConnection sqlConnection = null;
            DataSet ds = null;
            DataTable dt = null;
            try
            {
                string connectionString = string.Empty;
                connectionString = $@"server=192.168.8.232;database=ddmes;uid=DDB2MESAdmin;pwd=Yhqe4csJXJ4W5$%;";

                StringBuilder query = new StringBuilder();
                query.AppendLine($" SELECT  A.SITEID, ");
                query.AppendLine($"         A.FACILITYID, ");
                query.AppendLine($"         D.FACILITYNAME, ");
                query.AppendLine($"         B.PROCESSSEGMENTID, ");
                query.AppendLine($"         B.PROCESSSEGMENTNAME, ");
                query.AppendLine($"         A.SUBCATEGORY, ");
                query.AppendLine($"         C.EQUIPMENTID AS MAINEQUIPMENTID, ");
                query.AppendLine($"         C.EQUIPMENTNAME AS MAINEQUIPMENTNAME, ");
                query.AppendLine($"         A.EQUIPMENTID, ");
                query.AppendLine($"         A.EQUIPMENTNAME, ");
                query.AppendLine($"         A.DESCRIPTION, ");
                query.AppendLine($"         A.OPERATIONMODE, ");
                query.AppendLine($"         A.CONTROLMODE, ");
                query.AppendLine($"         A.LASTTRACKINLOTID, ");
                query.AppendLine($"         A.LASTTRACKOUTLOTID, ");
                query.AppendLine($"         A.MAKER, ");
                query.AppendLine($"         A.EQPSTATE, ");
                query.AppendLine($"         A.LOCATION ");
                query.AppendLine($"         , E.PLANDATE ");
                query.AppendLine($" FROM    CIM_EQUIPMENT A (nolock) ");
                query.AppendLine($"         LEFT JOIN  CIM_PROCESSSEGMENT B (nolock) ON A.PROCESSSEGMENTID = B.PROCESSSEGMENTID AND A.SITEID = B.SITEID ");
                query.AppendLine($"         LEFT JOIN  CIM_EQUIPMENT C (nolock) ON A.PARENTID = C.EQUIPMENTID AND A.SITEID = C.SITEID ");
                query.AppendLine($"         LEFT JOIN  CIM_FACILITY D (nolock) ON A.PHYSICALLOCATION = D.FACILITYID AND A.SITEID = D.SITEID ");
                query.AppendLine($"         LEFT JOIN  (SELECT SITEID, EQUIPMENTID, MIN(PLANSTART) PLANDATE FROM DD_SEGMENTPMDETAIL (nolock) WHERE PLANSTART >= '{DateTime.Now.ToString("yyyyMMdd")}' GROUP BY SITEID, EQUIPMENTID) E ON A.EQUIPMENTID = E.EQUIPMENTID AND A.SITEID = E.SITEID ");
                //query.AppendLine($" WHERE   A.SITEID='1130' ");

                sqlConnection = new SqlConnection();
                sqlConnection.ConnectionString = connectionString;
                sqlConnection.Open();

                SqlCommand sqlCommand = new SqlCommand();
                sqlCommand.Connection = sqlConnection;
                sqlCommand.CommandType = CommandType.Text;
                sqlCommand.CommandText = query.ToString();

                ds = new DataSet();
                SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlCommand);
                sqlAdapter.Fill(ds);
                sqlConnection.Close();

                if (ds != null && ds.Tables.Count > 0) dt = ds.Tables[0];
                return dt;
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
                return null;
            }
            finally
            {
                if (sqlConnection != null && sqlConnection.State != ConnectionState.Closed)
                {
                    sqlConnection.Close();
                    sqlConnection.Dispose();
                }
            }
        }

        /// <summary>
        /// SMB Log Files
        /// </summary>
        /// <param name="fileItems"></param>
        /// <returns></returns>
        private LogFile[] GetLogFiles(FileInfo[] fileItems)
        {
            LogFile[] logFiles = fileItems
                .Select(item => new LogFile
                {
                    Account = this.Account,
                    FullName = item.FullName,
                    Length = item.Length,
                    CreationTime = item.CreationTime,
                    LastAccessTime = item.LastAccessTime,
                    LastWriteTime = item.LastWriteTime
                })
                .OrderByDescending(x => x.Name)
                .ToArray();

            return logFiles;
        }

        /// <summary>
        ///  FTPS Log Files
        /// </summary>
        /// <param name="fileItems"></param>
        /// <returns></returns>
        private LogFile[] GetLogFiles(FtpListItem[] fileItems)
        {
            LogFile[] logFiles = fileItems.Where(item => item.Type == FtpFileSystemObjectType.File)
                .Select(item => new LogFile
                {
                    Account = this.Account,
                    FullName = item.FullName,
                    Length = item.Size,
                    CreationTime = item.Modified,
                    LastAccessTime = item.Modified,
                    LastWriteTime = item.Modified
                })
                .OrderByDescending(x => x.Name)
                .ToArray();

            return logFiles;
        }

        /// <summary>
        /// SFTP Log Files
        /// </summary>
        /// <param name="fileItems"></param>
        /// <returns></returns>
        private LogFile[] GetLogFiles(ISftpFile[] fileItems)
        {
            LogFile[] logFiles = fileItems.Where(item => !item.IsDirectory && item.Name != "." && item.Name != "..")
                .Select(item => new LogFile
                {
                    Account = this.Account,
                    FullName = item.FullName,
                    Length = item.Length,
                    CreationTime = item.LastAccessTime,
                    LastAccessTime = item.LastAccessTime,
                    LastWriteTime = item.LastWriteTime
                })
                .OrderByDescending(x => x.Name)
                .ToArray();

            return logFiles;
        }

        /// <summary>
        /// Fts Log Files jhlim 20250202
        /// </summary>
        /// <param name="fileItems"></param>
        /// <returns></returns>
        private LogFile[] GetFtpslogFiles(object fileItems)
        {
            LogFile[] logFiles = ((FtpListItem[])fileItems).Where(item => item.Type == FtpFileSystemObjectType.File)
                .Select(item => new LogFile
                {
                    Account = this.Account,
                    FullName = item.FullName,
                    Length = item.Size,
                    CreationTime = item.Modified,
                    LastAccessTime = item.Modified,
                    LastWriteTime = item.Modified
                })
                .OrderByDescending(x => x.Name)
                .ToArray();

            return logFiles;
        }

        #endregion

    }

}
