using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using DiscordBotCore.Bot;
using DiscordBotCore.Online;
using DiscordBotCore.Online.Helpers;
using DiscordBotCore.Others;
using DiscordBotCore.Others.Actions;
using DiscordBotCore.Others.Exceptions;
using DiscordBotCore.Others.Settings;
using DiscordBotCore.Modules;
using DiscordBotCore.Plugin;
using DiscordBotCore.Interfaces.Modules;
using DiscordBotCore.Repository;
namespace DiscordBotCore
{
///
/// The main Application and its components
///
public sealed class Application
{
///
/// Defines the current application. This is a singleton class
///
public static Application CurrentApplication { get; private set; } = null!;
private static readonly string _ConfigFile = "./Data/Resources/config.json";
private static readonly string _PluginsDatabaseFile = "./Data/Resources/plugins.json";
private static readonly string _ResourcesFolder = "./Data/Resources";
private static readonly string _PluginsFolder = "./Data/Plugins";
private static readonly string _LogsFolder = "./Data/Logs";
public ModuleManager ModuleManager = null!;
public DiscordBotApplication DiscordBotClient { get; set; } = null!;
public List ServerIDs => ApplicationEnvironmentVariables.GetList("ServerID", new List());
public string PluginDatabase => ApplicationEnvironmentVariables.Get("PluginDatabase", _PluginsDatabaseFile);
public CustomSettingsDictionary ApplicationEnvironmentVariables { get; private set; } = null!;
public InternalActionManager InternalActionManager { get; private set; } = null!;
public PluginManager PluginManager { get; private set; } = null!;
///
/// Create the application. This method is used to initialize the application. Can not initialize multiple times.
///
/// A function that will be called when a module is required to be installed. If set to default, will use the built in method(console)
public static async Task CreateApplication(Func? moduleRequirementsSolver)
{
if (!await OnlineFunctions.IsInternetConnected())
{
Console.WriteLine("No internet connection detected. Exiting ...");
Environment.Exit(0);
}
if (CurrentApplication is not null)
{
return;
}
CurrentApplication = new Application();
Directory.CreateDirectory(_ResourcesFolder);
Directory.CreateDirectory(_PluginsFolder);
Directory.CreateDirectory(_LogsFolder);
CurrentApplication.ApplicationEnvironmentVariables = await CustomSettingsDictionary.CreateFromFile(_ConfigFile, true);
CurrentApplication.ApplicationEnvironmentVariables.Add("PluginFolder", _PluginsFolder);
CurrentApplication.ApplicationEnvironmentVariables.Add("ResourceFolder", _ResourcesFolder);
CurrentApplication.ApplicationEnvironmentVariables.Add("LogsFolder", _LogsFolder);
CurrentApplication.ModuleManager = new ModuleManager(ModuleRepository.SolveRepo());
await CurrentApplication.ModuleManager.LoadModules();
var requirements = await CurrentApplication.ModuleManager.CheckRequiredModules();
if(requirements.RequireAny)
{
moduleRequirementsSolver ??= requirement => CurrentApplication.ModuleManager.SolveRequirementIssues(requirement);
await moduleRequirementsSolver(requirements);
await CurrentApplication.ModuleManager.LoadModules();
}
Logger._LoggerModule = CurrentApplication.ModuleManager.GetLoadedModuleWithTag(ModuleType.Logger);
if (!File.Exists(_PluginsDatabaseFile))
{
List plugins = new();
await JsonManager.SaveToJsonFile(_PluginsDatabaseFile, plugins);
}
CurrentApplication.PluginManager = new PluginManager(PluginRepository.SolveRepo());
await CurrentApplication.PluginManager.UninstallMarkedPlugins();
await CurrentApplication.PluginManager.CheckForUpdates();
CurrentApplication.InternalActionManager = new InternalActionManager();
await CurrentApplication.InternalActionManager.Initialize();
}
public static async Task InvokeMethod(string moduleName, string methodFriendlyName, params object[] parameters)
{
var module = CurrentApplication.ModuleManager.GetModule(moduleName);
var methodName = module.Value.MethodMapping[methodFriendlyName];
await CurrentApplication.ModuleManager.InvokeMethod(module.Value, methodName, parameters);
}
public static async Task