using System.Reflection;

using anbs_cp.Classes;

using FileSplitter.Console.Classes;
using FileSplitter.Shared.Classes;
using FileSplitter.Shared.Enums;

string assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? string.Empty;

//Инициализирую список параметров
ConsoleParamsParser consoleParser = new(Environment.GetCommandLineArgs());

//Приветственное сообщение
Console.WriteLine("********************************************************************************");
Console.WriteLine($"\t{Localization.AppTitle}");
Console.WriteLine($"\t{string.Format(Localization.AppVersion, assemblyVersion)}");
Console.WriteLine(
    $"\t{string.Format(Localization.AppCopyrights, DateTime.Now.Year == 2023 ? "2023" : $"2023 - {DateTime.Now.Year}")}");
Console.WriteLine("********************************************************************************");



//Разделение файлов по параметрам
if (consoleParser.HasParam("split"))
    return FileSplit4Params(consoleParser);

//Соединение файлов по параметрам
if (consoleParser.HasParam("join"))
    return FileJoin4Params(consoleParser);

//Если нет параметров, то запускаем интерактивный режим
return StartInteractive();

//Запуск интерактивного режима
static int StartInteractive () => (int) Executor.DoInteractive();

//Функция разделения файлов для параметров
static int FileSplit4Params (ConsoleParamsParser @params)
{
    //Проверяю наличие параметров
    if (!@params.HasParam("-fn") || !@params.HasParam("-td") || !@params.HasParam("-ps"))
    {
        //- вывожу сообщение
        Console.WriteLine(Localization.MessageNoParametersForSplit);

        //- прерываю
        return (int)FsExitCode.ecInvalidParameters;
    }

    //Получаю параметры
    //- имя исходного файла
    string fileName = @params.GetValue("-fn") ?? string.Empty;
    //- папка для сохранения разбиения
    string targetDir = @params.GetValue("-td") ?? string.Empty;
    //- размер части
    long partSize = TypeConverter.StrToInt64(@params.GetValue("-ps") ?? string.Empty);
    //- параметры
    List<FileSplitOptions> options = new();

    //Проверяю параметры разбиения
    //- отключена ли проверка хэша
    if (@params.HasParam("/NoCheckHash"))
        options.Add(FileSplitOptions.fsoNoCheckHash);
    //- нужно ли удалять исходный файл
    if (@params.HasParam("/DeleteSource"))
        options.Add(FileSplitOptions.fsoDeleteSourceFileAfterSplit);
    //- нужно ли шифровать файл информации
    if (@params.HasParam("/EncryptInfoFile"))
        options.Add(FileSplitOptions.fsoEncryptInfoFile);

    //Получаю параметры консоли
    bool silent = @params.HasParam("--silent");

    //Выполняю разбиение
    return (int)Executor.DoSplit(fileName, targetDir, partSize, silent, options);
}

//Функция объединения для параметров
static int FileJoin4Params (ConsoleParamsParser @params)
{
    //Проверяю наличие параметров
    if (!@params.HasParam("-ifn") || !@params.HasParam("-tfn"))
    {
        //- вывожу сообщение
        Console.WriteLine(Localization.MessageNoParametersForSplit);

        //- прерываю
        return (int)FsExitCode.ecInvalidParameters;
    }

    //Получаю параметры
    //- имя файла с информацией о разбиении
    string infoFileName = @params.GetValue("-ifn") ?? string.Empty;
    //- имя целевого файла
    string targetFileName = @params.GetValue("-tfn") ?? string.Empty;
    //- параметры
    List<FileJoinOptions> options = new();

    //Проверяю параметры разбиения
    //- отключена ли проверка хэша
    if (@params.HasParam("/NoCheckHash"))
        options.Add(FileJoinOptions.fjoNoCheckHash);
    //- нужно ли удалять исходные файлы
    if (@params.HasParam("/DeleteSource"))
        options.Add(FileJoinOptions.fjoDeleteSourceFilesAfterJoin);
    //- нужно ли дешифровать файл информации
    if (@params.HasParam("/DecryptInfoFile"))
        options.Add(FileJoinOptions.fjoInfoFileIsEncrypted);
    //- нужно ли отключить проверку версии файла информации
    if (@params.HasParam("/IgnoreVersion"))
        options.Add(FileJoinOptions.fjoIgnoreSupportedScriptVersion);
    //- нужно ли отключить проверку объединённого файла на корректность
    if (@params.HasParam("/SkipCheck"))
        options.Add(FileJoinOptions.fjoSkipCheckJoinedFile);

    //Получаю параметры консоли
    bool silent = @params.HasParam("--silent");

    return (int)Executor.DoJoin(infoFileName, targetFileName, silent, options);
}