using System;
using Pokemon_3D_Server_Core.RCON_Client_Listener.Uploader;
using Pokemon_3D_Server_Core.RCON_GUI_Client_Listener.Downloader;
using Pokemon_3D_Server_Core.Server_Client_Listener.Commands;
using Pokemon_3D_Server_Core.Server_Client_Listener.Loggers;
using Pokemon_3D_Server_Core.Server_Client_Listener.Players;
using Pokemon_3D_Server_Core.Server_Client_Listener.Servers;
using Pokemon_3D_Server_Core.Server_Client_Listener.Settings;
using Pokemon_3D_Server_Core.Server_Client_Listener.Worlds;
using Pokemon_3D_Server_Core.Shared.jianmingyong;
using Pokemon_3D_Server_Core.Shared.jianmingyong.Modules;

namespace Pokemon_3D_Server_Core
{
    /// <summary>
    ///     Class containing all important features.
    /// </summary>
    public class Core
    {
        /// <summary>
        ///     Get Setting.
        /// </summary>
        public static Setting Setting { get; private set; }

        /// <summary>
        ///     Get Logger.
        /// </summary>
        public static LoggerCollection Logger { get; private set; }

        /// <summary>
        ///     Get Updater.
        /// </summary>
        public static Updater Updater { get; private set; }

        /// <summary>
        ///     Get Pokemon 3D Listener.
        /// </summary>
        public static Listener Listener { get; private set; }

        /// <summary>
        ///     Get RCON Listener.
        /// </summary>
        public static RCON_Client_Listener.Servers.Listener RCONListener { get; private set; }

        /// <summary>
        ///     Get Comamnd List.
        /// </summary>
        public static CommandCollection Command { get; private set; }

        /// <summary>
        ///     Server Main Entry Point - Initialize as many things as possible here.
        ///     Order is important here, any additional initialization should be place at the bottom.
        /// </summary>
        /// <param name="directory">Start Directory.</param>
        public static void Start(string directory)
        {
            try
            {
                // Initialize Setting
                Setting = new Setting(directory);

                // Initialize Logger.
                Logger = new LoggerCollection();
                Logger.Start();

                if (Setting.Load())
                {
                    Setting.Save();
                }
                else
                {
                    Setting.Save();
                    Environment.Exit(0);
                    return;
                }

                // Initialize Updater
                if (Setting.CheckForUpdate)
                {
                    Updater = new Updater();
                    Updater.Update();
                }

                if (Setting.MainEntryPoint == Setting.MainEntryPointType.jianmingyong_Server)
                {
                    // Initialize Listener.
                    Listener = new Listener();
                    Listener.Start();

                    // Initialize RCONListener.
                    if (Setting.RCONEnable)
                    {
                        RCONListener = new RCON_Client_Listener.Servers.Listener();
                        RCONListener.Start();
                    }
                }

                // Initialize Command.
                Command = new CommandCollection();
                Command.AddCommand();
            }
            catch (Exception ex)
            {
                ex.CatchError();
            }
        }

        /// <summary>
        ///     Dispose all background worker for the thread to dispose.
        /// </summary>
        public static void Dispose()
        {
            Listener?.Dispose();
            RCONListener?.Dispose();
            Logger?.Dispose();
        }

        #region Pokemon 3D Listener

        /// <summary>
        ///     Get Player Collection.
        /// </summary>
        public static PlayerCollection Player { get; } = new PlayerCollection();

        /// <summary>
        ///     Get World.
        /// </summary>
        public static World World { get; } = new World();

        #endregion Pokemon 3D Listener

        #region RCON Listener

        /// <summary>
        ///     Get RCON Player Collection.
        /// </summary>
        public static RCON_Client_Listener.Players.PlayerCollection RCONPlayer { get; } = new RCON_Client_Listener.Players.PlayerCollection();

        /// <summary>
        ///     Get RCON Upload Queue.
        /// </summary>
        public static UploaderQueue RCONUploadQueue { get; } = new UploaderQueue();

        #endregion

        #region RCON GUI Listener

        /// <summary>
        ///     Get RCON Listener.
        /// </summary>
        public static RCON_GUI_Client_Listener.Servers.Listener RCONGUIListener { get; set; }

        /// <summary>
        ///     Get RCON GUI Download Queue.
        /// </summary>
        public static DownloaderQueue RCONGUIDownloadQueue { get; } = new DownloaderQueue();

        #endregion RCON GUI Listener
    }
}