using DDUtilityApp.LOGPARSER;
using DDUtilityApp.LOGPARSER.PARSER;
using DDUtilityApp.MONGO;
using JWH;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Security.Principal;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DDUtilityApp
{

    static class Program
    {

        /// <summary>
        /// 해당 응용 프로그램의 주 진입점입니다.
        /// </summary>
        [STAThread]
        static void Main(params string[] args)
        {
            try
            {
                XLogger.Instance.Info("START");
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);

                Form frm = null;

                if (args.Length > 0)
                {
                    if (string.Compare(args[0], "FrmLogParser", true) == 0 && args.Length >= 3)
                    {
                        FrmLogParser frmLogParser = new FrmLogParser(new EisParser0(), args[1], args[2]);
                        frm = frmLogParser;
                    }
                    if (string.Compare(args[0], "FrmFDCMongo", true) == 0)
                    {
                        FrmFDCMongo frmFDCMongo = new FrmFDCMongo();
                        if (args.Length > 1) frmFDCMongo.EquipmentID = args[1];
                        if (args.Length > 2)
                        {
                            DateTime dateTime = DateTime.Now.Date;
                            DateTime.TryParse(args[2], out dateTime);
                            frmFDCMongo.DateTimeStart = dateTime;
                        }
                        if (args.Length > 3)
                        {
                            DateTime dateTime = DateTime.Now.AddDays(1).Date;
                            DateTime.TryParse(args[3], out dateTime);
                            frmFDCMongo.DateTimeEnd = dateTime;
                        }
                        frm = frmFDCMongo;
                    }
                }
                
                if (frm == null)
                {
                    #region [ FrmMain ]

                    FrmMain frmMain = new FrmMain();
                    frmMain.Text = $"[EverOne] DDUtility - Ver. {Application.ProductVersion}";
                    frmMain.MinimizeBox = false;
                    frmMain.MaximizeBox = false;
                    frmMain.FormBorderStyle = FormBorderStyle.FixedDialog;

                    #region [ 버튼 생성 정보 ]
                    frmMain.Buttons.Add("EIS Log Viewer", new EisParser0());
                    frmMain.Buttons.Add("MES Log Download", typeof(MESDOWNLOADER.ServerLog));
                    //frmMain.Buttons.Add("MIS Log Viewer", new AgvParser()); // 제거 
                    frmMain.Buttons.Add("FDC Mongo Viewer", typeof(MONGO.FrmFDCMongo));
                    frmMain.Buttons.Add("HSMS Converter", typeof(LOGPARSER.FrmHsmsViewer));
                    frmMain.Buttons.Add("TIB Simulator", typeof(TIBRENDEZVOUS.FrmSimulator01));
                    frmMain.Buttons.Add("TibcoConfig.Xml", typeof(ETC.FrmTIbcoConfig));
#if DEBUG
                    frmMain.Buttons.Add("FTP Test", typeof(SPECDOCUMENT.FrmSpecDocument));
#endif
                    #endregion

                    Application.Run(frmMain);

                    if (frmMain.DialogResult != DialogResult.OK) return;
                    if (frmMain.SelectedObject == null) return;
                    if (frmMain.SelectedObject is Type)
                    {
                        Type frmType = frmMain.SelectedObject as Type;
                        // 목록에 등록된 클래스는 관리자 권한으로 실행
                        if (new string[] { "FRMTIBCOCONFIG" }.Contains(frmType.Name.ToUpper()))
                        {
                            if (IsAdministrator() == false)
                            {
                                try
                                {
                                    ProcessStartInfo processStartInfo = new ProcessStartInfo();
                                    processStartInfo.UseShellExecute = true;
                                    processStartInfo.FileName = Application.ExecutablePath;
                                    processStartInfo.WorkingDirectory = Environment.CurrentDirectory;
                                    processStartInfo.Verb = "runas";
                                    Process process = Process.Start(processStartInfo);

                                    return;
                                }
                                catch (Exception ex)
                                {
                                    XLogger.Instance.Warn(ex);
                                }
                            }
                        }

                        Assembly assembly = Assembly.GetAssembly(frmType);
                        frm = assembly.CreateInstance(frmType.FullName) as Form;
                    }
                    else if (frmMain.SelectedObject is LogParser)
                    {
                        FrmLogParser frmLogParser = new FrmLogParser();
                        frmLogParser.LogParser = frmMain.SelectedObject as LogParser;
                        frm = frmLogParser;
                    }

                    #endregion
                }

                if (frm == null) return;

                frm.StartPosition = GlobalVariable.Instance.FormStartPosition;
                frm.WindowState = GlobalVariable.Instance.FormWindowState;

                System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(GlobalVariable.Instance.FormLocation, GlobalVariable.Instance.FormSize);
                Screen screen = Screen.FromRectangle(rectangle);

                System.Drawing.Size minimumSize = frm.MinimumSize;
                if (screen.WorkingArea.Width < frm.MinimumSize.Width) minimumSize.Width = screen.WorkingArea.Width;
                if (screen.WorkingArea.Height < frm.MinimumSize.Height) minimumSize.Height = screen.WorkingArea.Height;
                frm.MinimumSize = minimumSize;

                frm.Location = GlobalVariable.Instance.FormLocation;
                frm.Size = GlobalVariable.Instance.FormSize;
                if ((frm.MinimumSize.Width > GlobalVariable.Instance.FormSize.Width)
                    || (frm.MinimumSize.Height > GlobalVariable.Instance.FormSize.Height)
                    )
                {
                }

                // Exception Handling
                AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException;
                Application.ThreadException += Application_ThreadException;

                Application.Run(frm);

                GlobalVariable.Instance.FormStartPosition = frm.StartPosition;
                GlobalVariable.Instance.FormWindowState = frm.WindowState;
                GlobalVariable.Instance.FormLocation = frm.Location;
                if (frm.WindowState == FormWindowState.Normal) GlobalVariable.Instance.FormSize = frm.Size;
                GlobalVariable.Instance.SaveSetting();

                XLogger.Instance.Info("END");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                XLogger.Instance.Fatal(ex);
            }
        }

        public static bool IsAdministrator()
        {
            WindowsIdentity identity = WindowsIdentity.GetCurrent();

            if (identity != null)
            {
                WindowsPrincipal principal = new WindowsPrincipal(identity);
                return principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
            return false;
        }

        /// <summary>
        /// AppDomain.UnhandledException
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                Exception ex = e.ExceptionObject as Exception;
                XLogger.Instance.Fatal(ex);
                if (e.IsTerminating) throw new Exception(ex.Message);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

        /// <summary>
        /// Application.ThreadException
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            try
            {
                Exception ex = e.Exception as Exception;
                XLogger.Instance.Fatal(ex);
                MessageBox.Show(ex.Message, "Application Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                XLogger.Instance.Fatal(ex);
            }
        }

    }

}
