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

using NLog;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Post
{
    public class ConstFunc
    {
        public string homePath = "";

        public ConstFunc()
        {
            homePath = Environment.GetEnvironmentVariable("POST_HOME");
        }

        #region GetDirectoryPath() : directory 경로 가져옴, 환경변수에 등록된 경로를 우선적으로 가져온다.
        public string GetDirectoryPath(string type)
        {
            string result = "";
            string logMessage = "";
            ConstValues constValues = new ConstValues();

            try
            {
                if (type.Equals(constValues.CONST_CONFIG_POST, StringComparison.OrdinalIgnoreCase))
                {
                    // ## Properties.Resources.FilePathOfPostConfig를 "\\config\\"로 대체
                    result = homePath + "\\config\\";
                }
                else if (type.Equals(constValues.CONST_CONFIG_CONN, StringComparison.OrdinalIgnoreCase))
                {
                    // ## Properties.Resources.FilePathOfConn "\\config\\conn\\"로 대체
                    result = homePath + "\\config\\conn\\";
                }
                else if (type.Equals(constValues.CONST_TRACE, StringComparison.OrdinalIgnoreCase))
                {
                    // ## Properties.Resources.FilePathOfTrace "\\trace"로 대체
                    result = homePath + "\\trace\\";
                }
                else if (type.Equals(constValues.CONST_CHECKPOINT, StringComparison.OrdinalIgnoreCase))
                {
                    result = homePath + "\\checkpoint\\";
                }
                else
                {
                    Console.WriteLine("[ GetDirectoryPath ] invalid type : " + type);
                }
            }
            catch (Exception e)
            {
                logMessage = "[System Exception] ConstFunc GetDirectoryPath() exception : " + e.Message.ToString();
                WriteLog("FATAL", logMessage, "util_logger", "", null);
            }

            return result;
        }
        #endregion

        #region WriteLog() : 로그 작성
        public void WriteLog(string logType, string message, string loggerName, string alias, object config)
        {
            try
            {
                string logBackup = "";
                string logLevel = "";
                Logger log = null;
                ConfigPost postConfig = new ConfigPost();
                ConstValues constValues = new ConstValues();

                if (config != null)
                {
                    if (loggerName.Equals(constValues.CONST_LOGGER_POST, StringComparison.OrdinalIgnoreCase))
                    {
                        postConfig = (ConfigPost)config;
                        logBackup = postConfig.LOG_BACKUP;
                        logLevel = postConfig.LOG_LEVEL;
                    }
                }

                NLog.Targets.FileTarget target;
                String fileName = "";
                String archiveFileName = "";

                if (loggerName.Equals(constValues.CONST_LOGGER_POST, StringComparison.OrdinalIgnoreCase))
                {
                    log = LogManager.GetLogger(constValues.CONST_LOGGER_POST);
                    target = LogManager.Configuration.FindTargetByName(constValues.CONST_POST) as NLog.Targets.FileTarget;
                    // ## Properties.Resources.FilePathOfLogPost 를 "\\logs\\post\\"로 대체
                    fileName = homePath + "\\logs\\post\\" + alias + ".log";
                    target.FileName = fileName;
                    archiveFileName = homePath + "\\logs\\post\\" + alias + "_${date:format=yyyyMMdd}" + "_{#####}.log";
                    target.ArchiveFileName = archiveFileName;
                    target.Encoding = Encoding.UTF8;
                    if (logBackup.Equals(constValues.CONST_LOG_BACKUP_ALL, StringComparison.OrdinalIgnoreCase))
                        target.ArchiveEvery = NLog.Targets.FileArchivePeriod.Day;
                    else if (logBackup.Equals(constValues.CONST_LOG_BACKUP_ONE, StringComparison.OrdinalIgnoreCase))
                        target.MaxArchiveFiles = 2;
                    else
                        target.MaxArchiveFiles = 1;
                }

                target = null;
                fileName = null;
                archiveFileName = null;

                if (logLevel.Equals(constValues.CONST_LOG_LEVEL_TRACE, StringComparison.OrdinalIgnoreCase))
                {
                    if (logType.Equals(constValues.CONST_LOGGER_TYPE_TRACE, StringComparison.OrdinalIgnoreCase))
                        log.Trace(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_DEBUG, StringComparison.OrdinalIgnoreCase))
                        log.Debug(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_INFO, StringComparison.OrdinalIgnoreCase))
                        log.Info(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_WARN, StringComparison.OrdinalIgnoreCase) || logType.Equals(constValues.CONST_LOGGER_TYPE_WARNNING, StringComparison.OrdinalIgnoreCase))
                        log.Warn(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_ERROR, StringComparison.OrdinalIgnoreCase))
                        log.Error(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_FATAL, StringComparison.OrdinalIgnoreCase))
                        log.Fatal(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_ABSOLUTE, StringComparison.OrdinalIgnoreCase))
                        log.Info(message);
                }
                else if (logLevel.Equals(constValues.CONST_LOG_LEVEL_DEBUG, StringComparison.OrdinalIgnoreCase))
                {
                    if (logType.Equals(constValues.CONST_LOGGER_TYPE_DEBUG, StringComparison.OrdinalIgnoreCase))
                        log.Debug(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_INFO, StringComparison.OrdinalIgnoreCase))
                        log.Info(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_WARN, StringComparison.OrdinalIgnoreCase) || logType.Equals(constValues.CONST_LOGGER_TYPE_WARNNING, StringComparison.OrdinalIgnoreCase))
                        log.Warn(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_ERROR, StringComparison.OrdinalIgnoreCase))
                        log.Error(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_FATAL, StringComparison.OrdinalIgnoreCase))
                        log.Fatal(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_ABSOLUTE, StringComparison.OrdinalIgnoreCase))
                        log.Info(message);
                }
                else if (logLevel.Equals(constValues.CONST_LOG_LEVEL_WARN, StringComparison.OrdinalIgnoreCase))
                {
                    if (logType.Equals(constValues.CONST_LOGGER_TYPE_WARN, StringComparison.OrdinalIgnoreCase) || logType.Equals(constValues.CONST_LOGGER_TYPE_WARNNING, StringComparison.OrdinalIgnoreCase))
                        log.Warn(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_ERROR, StringComparison.OrdinalIgnoreCase))
                        log.Error(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_FATAL, StringComparison.OrdinalIgnoreCase))
                        log.Fatal(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_ABSOLUTE, StringComparison.OrdinalIgnoreCase))
                        log.Info(message);
                }
                else if (logLevel.Equals(constValues.CONST_LOG_LEVEL_ERROR, StringComparison.OrdinalIgnoreCase))
                {
                    if (logType.Equals(constValues.CONST_LOGGER_TYPE_ERROR, StringComparison.OrdinalIgnoreCase))
                        log.Error(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_FATAL, StringComparison.OrdinalIgnoreCase))
                        log.Fatal(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_ABSOLUTE, StringComparison.OrdinalIgnoreCase))
                        log.Info(message);
                }
                else if (logLevel.Equals(constValues.CONST_LOG_LEVEL_FATAL, StringComparison.OrdinalIgnoreCase))
                {
                    if (logType.Equals(constValues.CONST_LOGGER_TYPE_FATAL, StringComparison.OrdinalIgnoreCase))
                        log.Fatal(message);
                    else if (logType.Equals(constValues.CONST_LOGGER_TYPE_ABSOLUTE, StringComparison.OrdinalIgnoreCase))
                        log.Info(message);
                }
                else   // default level 은 info
                {
                    if (logType.Equals("INFO", StringComparison.OrdinalIgnoreCase))
                        log.Info(message);
                    else if (logType.Equals("WARN", StringComparison.OrdinalIgnoreCase) || logType.Equals(constValues.CONST_LOGGER_TYPE_WARNNING, StringComparison.OrdinalIgnoreCase))
                        log.Warn(message);
                    else if (logType.Equals("ERROR", StringComparison.OrdinalIgnoreCase))
                        log.Error(message);
                    else if (logType.Equals("FATAL", StringComparison.OrdinalIgnoreCase))
                        log.Fatal(message);
                    else if (logType.Equals("ABSOLUTE", StringComparison.OrdinalIgnoreCase))
                        log.Info(message);
                }

                logBackup = null;
                logLevel = null;
                postConfig = null;
            }
            catch
            {
                // not supported
            }
        }
        #endregion

        #region IsFileReady() : file 사용 여부 체크
        public bool IsFileReady(string filename)
        {
            bool result = false;
            try
            {
                if (File.Exists(filename))
                {
                    using (FileStream inputStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        result = true;
                    }
                }
                else
                {
                    result = true;
                }
            }
            catch
            {
                // exception 처리불필요 무시하고 다음절차 실행
            }

            return result;
        }
        #endregion
    }
}
