using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Diagnostics;

namespace NewPosInstaller
{
    public partial class frmStart : Form
    {
        /// <summary>
        /// 작업 디렉토리 
        /// "C:\SPC_NewPosInstall\"
        /// </summary>
        public const string WorkDir = @"C:\SPC_NewPosInstall\";
        /// <summary>
        /// 로그 디렉토리 
        /// </summary>
        public const string LogDir = WorkDir + @"log\";

        private string _sourcePath = string.Empty; 
        private string _targetPath = string.Empty;
        private string _executeFile = string.Empty;

        private enum LogLevel
        {
            trace,
            Error,
            Exception,
        }
        private string[] LogLevelName = new string[] { "TRACE", "ERROR", "EXCEPTION" };

        public frmStart(string[] args)
        {

            InitializeComponent();

            WriteLog(LogLevel.trace
                   , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                   + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                   , string.Empty.PadRight(80, '='));

            WriteLog(LogLevel.trace
                   , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                   + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                   , "SPC NewPos Installer Update Start [version=" + Application.ProductVersion + "]");

            if (args.Length >= 2)
            {
                _sourcePath = args[0].Trim();
                _targetPath = args[1].Trim();
                _executeFile = args[2].Trim();
            }

            WriteLog(LogLevel.trace
                   , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                   + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                   , string.Format("SourcePath={0} TargetPath={1} ExecuteFile={2}" , _sourcePath, _targetPath, _executeFile));
        }

        private void Form_Load(object sender, EventArgs e)
        {
            try
            {
                // 화면 초기 위치 (윈도우 오른쪽 하단)
                int x = Screen.PrimaryScreen.WorkingArea.Size.Width - 400;
                int y = Screen.PrimaryScreen.WorkingArea.Size.Height - 150;
                this.Location = new Point(x, y);
            }
            catch (Exception ex)
            {
                WriteLog(LogLevel.trace
                       , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                       + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                       , ex.Message);
            }
        }

        private void Form_Closing(object sender, FormClosingEventArgs e)
        {
            try
            {
                string closeReason = string.Empty;
                switch (e.CloseReason)
                {
                    case CloseReason.ApplicationExitCall: closeReason = "ApplicationExitCall"; break;
                    case CloseReason.TaskManagerClosing: closeReason = "TaskManagerClosing"; break;
                    case CloseReason.FormOwnerClosing: closeReason = "FormOwnerClosing"; break;
                    case CloseReason.MdiFormClosing: closeReason = "MdiFormClosing"; break;
                    case CloseReason.UserClosing: closeReason = "UserClosing"; break;
                    case CloseReason.None:
                    default:
                        closeReason = "Unknown";
                        break;
                }

                WriteLog(LogLevel.trace
                       , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                       + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                       , string.Format("SPC NewPos Installer Update Stop [{0}]", closeReason));

            }
            catch (Exception ex)
            {
                WriteLog(LogLevel.trace
                       , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                       + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                       , ex.Message);
            }
        }

        private void frmStart_Shown(object sender, EventArgs e)
        {
            try
            {
                this.Visible = false;

                if (string.IsNullOrWhiteSpace(_sourcePath)) return;
                if (string.IsNullOrWhiteSpace(_targetPath)) return;
                if (string.IsNullOrWhiteSpace(_executeFile)) return;

                //POS Program 강제 종료
                Thread.Sleep(3000);
                var fileName = Path.GetFileNameWithoutExtension(_executeFile);
                for (var i = 0; i < 10; i++)
                {
                    Process[] arProcess = Process.GetProcessesByName(fileName);
                    if (arProcess.Length == 0) break;

                    try
                    {
                        arProcess[0].Kill();
                    }
                    catch { }
                    Thread.Sleep(1000);
                }

                string srcFile = Path.Combine(_sourcePath, _executeFile);
                string desFile = Path.Combine(_targetPath, _executeFile);

                File.Copy(srcFile, desFile, true);
                Thread.Sleep(3000);

                WriteLog(LogLevel.trace
                       , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                       + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                       , string.Format("Copy File {0} => {1}", srcFile, desFile));

                Process.Start(desFile);

                WriteLog(LogLevel.trace
                       , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                       + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                       , string.Format("Process.Start {0}", desFile));
            }
            catch (Exception ex)
            {
                WriteLog(LogLevel.Exception
                       , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                       + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                       , ex.Message);
            }
            finally
            {
                //WriteLog(LogLevel.trace
                //       , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                //       + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                //       , "SPC NewPos Installer Update Exit");
                Application.Exit();
            }
        }

        private void WriteLog(LogLevel logLevel, string function, string msg)
        {
            try
            {
                string levelName = LogLevelName[(int)logLevel];
                string logMsg = string.Format("{0:yyyy/MM/dd HH:mm:ss.fff} [{1}] {2} [{3:000000}] {4}"
                                             , DateTime.Now
                                             , LogLevelName[(int)logLevel].PadRight(10)
                                             , PadRightEx(function, 40)
                                             , msg.Length
                                             , msg
                                             );

                string fileName = string.Format("{0}_{1}.log", "NewPosInstaller", DateTime.Now.ToString("yyMMdd"));
                string filePath = Path.Combine(LogDir, fileName);
                Directory.CreateDirectory(LogDir);

                // 로그 기록
                bool bAppend = System.IO.File.Exists(filePath);
                using (System.IO.StreamWriter sw = new System.IO.StreamWriter(filePath, bAppend, Encoding.Default))
                {
                    sw.WriteLine(logMsg);
                    sw.Flush();
                }

            }
            catch { }
        }

        private string PadRightEx(string value, int length, char padChar = ' ')
        {
            string ret = value;
            try
            {
                if (ret.Length > length)
                    ret = ret.Substring(0, length);
                else
                    ret = ret.PadRight(length, padChar);
            }
            catch (Exception ex)
            {
                WriteLog(LogLevel.trace
                       , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                       + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                       , ex.Message);
            } 
            return ret;
        }
    }
}
