using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using System.Data;

namespace NewPosInstaller
{
    /// <summary>
    /// 프로그램 설치
    /// </summary>
    public class PosProgramInstall : Echo, IProcess
    {
        //private bool isStop = false; 

        public bool Execute()
        {
            bool retValue = false;
            
            string downFile = string.Empty;
            string downPath = string.Empty; 
            try
            {
                base.OnEcho("Check new POS program download");

                ComLog.WriteLog(ComLog.Level.trace
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , "Start");

                bool isApply = false; 

                // 압출툴 존재여부 확인, 없으면 FTP 서버에서 다운로드 받는다.
                downFile = "7za.exe";
                downPath = Path.Combine(DirInfo.WorkDir, downFile);
                isApply = true;
                if (File.Exists(downPath)) isApply = false;
                if (isApply)
                {
                    base.OnEcho(string.Format("Downloading the new POS program.\n[{0}]", downFile));

                    retValue = FtpDownload(DirInfo.WorkDir, downFile);
                    if (retValue == false) return retValue;

                    FileInfo f = new FileInfo(downPath);
                    if (f == null) return retValue = false;
                    if (f.Length == 0) return retValue = false; 
                }
                else
                {
                    ComLog.WriteLog(ComLog.Level.trace
                                  , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                                  + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                                  , string.Format("  => FTP Download Result={0} File={1}", "Skip", downFile));
                }

                // POS 프로그램 파일 다운로드
                downFile = string.IsNullOrWhiteSpace(ServerInfo.DownFile) ? "SPC.zip" : ServerInfo.DownFile;
                downPath = Path.Combine(DirInfo.DownDir, downFile);
                isApply = false;
                if (string.IsNullOrWhiteSpace(BasicInfo.PGMDownDate)) isApply = true;
                if (Directory.Exists(Path.Combine(DirInfo.InstallDir, @"BIN\")) == false) isApply = true;
                if (isApply)
                {
                    base.OnEcho(string.Format("Downloading the new POS program.\n[{0}]", downFile));

                    retValue = FtpDownload(DirInfo.DownDir, downFile);
                    if (retValue == false) return retValue;

                    FileInfo f = new FileInfo(downPath);
                    if (f == null) return retValue = false;
                    if (f.Length == 0) return retValue = false;

                    // 다운로드 일시 기록
                    BasicInfo.PGMDownDate = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
                }
                else
                {
                    ComLog.WriteLog(ComLog.Level.trace
                                  , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                                  + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                                  , string.Format("  => FTP Download Result={0} File={1}", "Skip", downFile));
                    return retValue = true;
                }

                // 압축해제
                base.OnEcho("The download file is unzipping.");
                ComLib.DeleteDirectoryInFile(DirInfo.TempDir, 2);
                ComLib.CreateDirectory(DirInfo.TempDir);
                retValue = ComLib.ExcuteUnzip(DirInfo.WorkDir, downPath, DirInfo.TempDir);

                ComLog.WriteLog(ComLog.Level.trace
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , string.Format("  => Download file unzip Result={0} File={1}", retValue ? "Success" : "Failed", downFile), true);
                if (retValue == false)
                {
                    ComLog.SendStatus(ComLog.InstallStatus.PosSetup, ComLog.InstallResult.Fail, "Download file unzip failed");
                    return false;
                } 

                // 폴더복사 
                base.OnEcho("The downloaded program is being copied.");
                ComLib.CreateDirectory(DirInfo.InstallDir);
                retValue = ComLib.DirectoryCopy(DirInfo.TempDir, DirInfo.InstallDir, "");
                //retValue = ComLib.DirectoryMove(DirInfo.TempDir, DirInfo.InstallDir);
                ComLog.WriteLog(ComLog.Level.trace
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , string.Format("  => Unzip file copy Result={0} DestDirctory={1}", retValue ? "Success" : "Failed", DirInfo.InstallDir), true);
                if (retValue == false)
                {
                    ComLog.SendStatus(ComLog.InstallStatus.PosSetup, ComLog.InstallResult.Fail, "Download file copy failed");
                    return false;
                } 

                // 프로그램 설치 일시 기록 
                BasicInfo.POSSetupDate = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
                ComLog.SendStatus(ComLog.InstallStatus.PosSetup, ComLog.InstallResult.Success, "New POS program down & copy success");

                return retValue;
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , "  => Exception : " + ex.Message);
                return retValue = false;
            }
            finally
            {
                ComLog.WriteLog(ComLog.Level.trace
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , string.Format("End, Result={0}", retValue ? "Success" : "Failed"));
            }
        }

        public void Stop()
        {
            //isStop = true;
        }

        private bool FtpFileExist(string svrPath)
        {
            bool retValue = false;
            try
            {
                FTP ftp = new FTP(ServerInfo.FtpIP, ServerInfo.FtpUser, ServerInfo.FtpPass);
                if (ftp == null) return false;

                return ftp.FTPFileExsit(svrPath);
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , "  => Exception : " + ex.Message);
                return false;
            }
            finally
            {
                ComLog.WriteLog(ComLog.Level.trace
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , string.Format("  => FTP File Exist, Result={0} File={1}", retValue ? "Success" : "Failed", svrPath), true);
            }
        }
        
        private bool FtpDownload(string downPath, string downFile)
        {
            bool retValue = false; 
            try
            {
                string svrPath = ServerInfo.FtpPath + downFile;
                string locPath = Path.Combine(downPath, downFile);

                ComLib.CreateDirectory(downPath);
                ComLib.FileDelete(locPath);

                FTP ftp = new FTP(ServerInfo.FtpIP, ServerInfo.FtpUser, ServerInfo.FtpPass);
                if (ftp == null) return false;
                return retValue = ftp.Download(svrPath, locPath);
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , "  => Exception : " + ex.Message);
                return false;
            }
            finally
            {
                ComLog.WriteLog(ComLog.Level.trace
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , string.Format("  => FTP Download Result={0} File={1}{2}", retValue ? "Success" : "Failed", downPath, downFile), true);
                System.Threading.Thread.Sleep(100);
            }
        }
    }
}
