using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace NewPosInstaller
{
    public class ComLog
    {
        public enum Level
        {
            trace,
            Error,
            Exception,
        }
        private static string[] LogLevelName = new string[] { "TRACE", "ERROR", "EXCEPTION" };

        /// <summary>
        /// 로그 리스터 시작
        /// </summary>
        /// <remarks>
        /// 디버그 모드에서는 출력되지 않는다.
        /// </remarks>
        public static void Start()
        {
            string fileName = DirInfo.LogDir + string.Format("{0}_{1}.log", "NewPosInstaller", DateTime.Now.ToString("yyMMdd"));

            Trace.Listeners.Clear();
            Trace.Listeners.Add(new TextWriterTraceListener(fileName));
        }

        public static void Stop()
        {
            Trace.Close();
            Trace.Listeners.Clear();
        }

        public static void WriteLog(ComLog.Level logLevel, string function, string msg, bool irtSend = false)
        {
            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
                                             );

                Trace.WriteLine(logMsg);
                Trace.Flush();

                // Exception이면, 강제서버전송.
                if (logLevel == Level.Exception) irtSend = true;

                if (irtSend)
                {
                    string logData = string.Format("{0} {1}", function, msg);
                    SendLog(logLevel, logData);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public static void WriteLog(ComLog.Level logLevel, string msg)
        {
            WriteLog(logLevel, "", msg);
        }

        //UserLog.WriteLogFile(UserCom.LOG_ERROR, System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
        //                    "SqlDB.SqlDB()", "Process Exception !!! " + e.ToString());
        public static void WriteLogFile(string pType, string pProject, string pFunction, string pMsg)
        {
            ComLog.Level loglevel = Level.trace;
            if (pType == ComLib.LOG_ERROR) loglevel = Level.Error; 

            WriteLog(loglevel, pFunction, pMsg);
        }

        public static void WriteLogFile(string pType, int pLogLevel, string pProject, string pFunction, string pMsg)
        {
            WriteLogFile(pType, pProject, pFunction, pMsg);
        }


        private static string PadLeftEx(string value, int length, char padChar = ' ')
        {
            string ret = value;
            try
            {
                if (ret.Length > length)
                    ret = ret.Substring(0, length);
                else
                    ret = ret.PadLeft(length, padChar);
            }
            catch { }
            return ret;
        }

        private static 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 { }
            return ret;
        }



        public enum InstallStatus
        { 
            InstallStart,       // 0 + 1 = 1
            PosSetup,           // 1
            DBCreate,           // 2
            ConfigMigration,    // 3
            DevcieMigration,    // 4
            KPSInfoUpload,
            TouchkeyUpload,
            FloavorUpload, 
            TableInfoUpload,
            EtcInfoMigration,
            InstallComplete,    // 10 + 1 = 11
            ApplicationExit,    //  
            PosOptionUpload,
        }
        public static class CheckStatus
        {
            /// <summary>
            /// 21 : POS 현재 해상도 정보  (800x600, 1024x768)
            /// </summary>
            public const string SCREEN_SIZE = "21";
            /// <summary>
            /// 22 : MSR(USB:KeybordWedge), MSR(Serial:Emulator), IC
            /// </summary>
            public const string CARD_READER_TYPE = "22";
            /// <summary>
            /// 23 : CAT 단말기 사용구분  (NONE:미사용, OLD:구형, NEW:구형)
            /// </summary>
            public const string CAT_TERM_TYPE = "23";
            /// <summary>
            /// 24 : AS-IS 점포코드 (삼립 점포코드 변경 대응)
            /// </summary>
            public const string OLD_STORE_CODE = "24";
            /// <summary>
            /// 25 : TPAY 사용유무 (NONE, USED)
            /// </summary>
            public const string TPAY_USE = "25";
            /// <summary>
            /// 26 : TPAY BLE 사용유무 (NONE, USED)
            /// </summary>
            public const string TPAY_BLE_USE = "26";
            /// <summary>
            /// 27 : OS Version
            /// </summary>
            public const string OSVersion = "27";
            /// <summary>
            /// 28 : 현재사용자계정 권한 
            /// </summary>
            public const string Permissions = "28";
        }

        public enum InstallResult
        { 
            Success, 
            Fail,
            Skip,
        }
        public static string[] InstallResultStr = new string[] { "SUCCESS", "FAIL", "SKIP" };

        public static void SendStatus(ComLog.InstallStatus status, ComLog.InstallResult result, string remarks)
        {
            try
            {
                string statusStr = ((int)status + 1).ToString("00");
                string value = InstallResultStr[(int)result];

                SendStatus(statusStr, value, remarks);
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , "  => Exception : " + ex.Message);
            }
        }

        public static bool SendStatus(string status, string value, string remarks)
        {
            try
            {
                ComLog.WriteLog(ComLog.Level.trace
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , string.Format("  => Status Status={0}, Value={1}, Remarks={2}", status, value, remarks), false);

                Hashtable htSendData = new Hashtable();
                Hashtable htRecvData = new Hashtable();

                // 통신해더 생성
                string commHead = ItemColumn.MakeCommHeader(0, "06");
                // 전송데이터
                htSendData.Add(Column.IQ_INSTALL_STATUS_INQ.DATA.INQ_TYPE, Column.IQ_INSTALL_STATUS_INQ.MSG_ID);
                htSendData.Add(Column.IQ_INSTALL_STATUS_INQ.DATA.STOR_CD, BasicInfo.StoreNo);
                htSendData.Add(Column.IQ_INSTALL_STATUS_INQ.DATA.POS_NO, BasicInfo.PosNo);
                htSendData.Add(Column.IQ_INSTALL_STATUS_INQ.DATA.STATUS, status);
                htSendData.Add(Column.IQ_INSTALL_STATUS_INQ.DATA.RESULT, value);
                htSendData.Add(Column.IQ_INSTALL_STATUS_INQ.DATA.REMARKS, ComLib.LeftH(remarks, 1000).Trim());
                htSendData.Add(Column.IQ_INSTALL_STATUS_INQ.DATA.RES_CD, "");

                NetworkJSON irt = new NetworkJSON();
                int ret = irt.IRTSendReceive(ServerInfo.SvrIP, ServerInfo.SvrPort, 1000 * 20, commHead, htSendData, ref htRecvData);
                if (ret != ComLib.OK)
                {
                    ComLog.WriteLog(ComLog.Level.Error
                                  , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                                  + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                                  , "  => Server communication error");
                    return false; 
                }
                string res = htRecvData[Column.IQ_INSTALL_STATUS_INQ.DATA.RES_CD].ToString();
                ComLog.WriteLog(res != "00" ? ComLog.Level.Error : ComLog.Level.trace
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , string.Format("  => Install Status send, RespCode={0}, Result={1}", res, res == "00" ? "Success" : "Failed"));

                return res == "00" ? true : false; 
            }
            catch (Exception ex)
            {
                ComLog.WriteLog(ComLog.Level.Exception
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , "  => Exception : " + ex.Message);
                return false; 
            }
        }

        public static void SendLog(ComLog.Level logType, string logData, string logTime = "")
        {
            try
            {
                if (string.IsNullOrWhiteSpace(logTime)) logTime = DateTime.Now.ToString("yyyyMMddHHmmssfff");

                Hashtable htSendData = new Hashtable();
                Hashtable htRecvData = new Hashtable();

                // 통신해더 생성
                string commHead = ItemColumn.MakeCommHeader(0, "06");
                // 전송데이터
                htSendData.Add(Column.IQ_INSTALL_LOG_INQ.DATA.INQ_TYPE, Column.IQ_INSTALL_LOG_INQ.MSG_ID);
                htSendData.Add(Column.IQ_INSTALL_LOG_INQ.DATA.STOR_CD, BasicInfo.StoreNo);
                htSendData.Add(Column.IQ_INSTALL_LOG_INQ.DATA.POS_NO, BasicInfo.PosNo);
                htSendData.Add(Column.IQ_INSTALL_LOG_INQ.DATA.LOG_TIME, logTime);
                htSendData.Add(Column.IQ_INSTALL_LOG_INQ.DATA.LOG_TYPE, ((int)logType).ToString());
                htSendData.Add(Column.IQ_INSTALL_LOG_INQ.DATA.LOG_DATA, ComLib.LeftH(logData, 990).Trim());

                NetworkJSON irt = new NetworkJSON();
                int ret = irt.IRTSendReceive(ServerInfo.SvrIP, ServerInfo.SvrPort, 1000 * 20, commHead, htSendData, ref htRecvData);
                if (ret != ComLib.OK)
                {
                    ComLog.WriteLog(ComLog.Level.Error
                                  , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                                  + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                                  , "  => Server communication error");
                }
                string res = htRecvData[Column.IQ_INSTALL_STATUS_INQ.DATA.RES_CD].ToString();
                ComLog.WriteLog(res != "00" ? ComLog.Level.Error : ComLog.Level.trace
                              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                              , string.Format("  => Install Log send, RespCode={0}, Result={1}", res, res == "00" ? "Success" : "Failed")); 

            }
            catch (Exception ex)
            {
                //ComLog.WriteLog(ComLog.Level.Exception
                //              , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "."
                //              + System.Reflection.MethodBase.GetCurrentMethod().Name + "()"
                //              , "  => Exception : " + ex.Message);
            }
        }
    }
}
