#ifndef PARAMETERMANAGER_H
#define PARAMETERMANAGER_H



#ifndef __linux__
#ifndef _WIN32
#error "Error Invalid System: Only for Linux and Windows systems!"
#endif
#endif

#include <iostream>
#include <getopt.h>
#include <string.h> // strlen
#include <sstream>
#include <sys/stat.h>
#include <fstream>
#include <vector>

#include <limits.h> // PATH_MAX
#include <unistd.h> // readlink()
#include <dirent.h>



#define UpdaterCloudUrlWithPath "https://cloud.obermui.de/s/tXz7SWdaPJ7TacZ/download?path=%2F&files="
#define SecondUpdaterCloudUrlWithPath "https://snew4.obermui.de/download?path=%2F&files="
#define VERSION "6.0.0"
#define DEFAULT_FILE_VERSION "2.5"

//default, anime, normal,
//suche: für jede katego. eine
//zu beginn, erst eiunmal serie suchen




enum Modus {
    EXIT = -1,
    DEFAULT_MODUS = 0,
    DIRECT_LINK_MODUS = 1,
    SEARCH_MODUS = 2,
    INFO_MODUS = 3,
    NEWS_MODUS = 4,
    UPDATE_MODUS = 5,
    REMOVE_SETTINGS_AND_CACHE_MODUS = 6,
    PRINT_LOG_FILE_MODUS = 7,
    PRINT_JD2_SKRIPT = 8,
    POPULAR_MODUS = 9

};

struct PAGE {
    PAGE() {}
    PAGE( std::string protocol, std::string url, std::string nameID, std::string urlAphabetSerienList, std::string urlDir, std::string popularSerien )
        :  protocol(protocol), name_id(nameID), url(url), urlAlphabetSerienList(urlAphabetSerienList), UrlDir(urlDir), popularSerien(popularSerien)
    {

    }
    std::string protocol, name_id, url, urlAlphabetSerienList,   UrlDir, popularSerien;
};

#include "logger.h"

//////Wichtig nach MODUS UND PAGE DECLARATION
#include "pageManager.h"


struct Settings {
    const std::string programName = "S_New4";

    //erst animes, dann alle seiten-seiten::
    const PAGE
        _anicio = PAGE( "https://" , "aniworld.to", "Animes", "/animes-alphabet", "/anime/stream/", "/beliebte-animes"),
    //alle serien - seiten:
        _sto = PAGE( "https://", "s.to", "Normale_Serien", "/serien-alphabet", "/serie/stream/", "/beliebte-serien"),
        _stoIP = PAGE( "http://", "186.2.175.5", "Normale_Serien", "/serien-alphabet", "/serie/stream/", "/beliebte-serien"),
        serienstreamto = PAGE("https://", "serienstream.to", "Normale_Serien", "/serien-alphabet", "/serie/stream/", "/beliebte-serien");

    //alle compakt
    const PAGE pagesALL[4] = { _anicio, _sto, _stoIP, /*_serienstreamsx, seriencam, */serienstreamto };

    std::vector<PAGE> pagesInUse; // Priority sorted
    bool useFirstPage = false;

    PAGE direktLink_explizitPage;


    Settings() {
        for(const auto &e : pagesALL)
            pagesInUse.push_back( e );
    }

// Wenn das Betriebsystem x86 ist:
#if defined (_X86_) || defined (__amd64__) || defined (_M_IX86)
    // Wenn das Betriebsystem LINUX ist und 64 Bit ist:
    #if defined (__linux) && ( defined (_LP64) || defined (__LP64__))
        const std::string VersionFileName =  std::string("Version-LINx86.txt");
        const std::string ProgrammFileName =  std::string("S_New4-LINx86");
    #else
        //Wenn das Betriebsystem Windows ist und 64 Bit ist
        #if defined (_WIN64)
            const std::string VersionFileName = std::string("Version-WINx86.txt");
            const std::string ProgrammFileName =  std::string("S_New4-WINx86.exe");
        #else
            //Ungültiges Betriebsystem => Error
            #error Kein Windows oder Linux 64 Bit System: Der Updater Fuktion wird nicht Funktionieren! Remove this Line in the Code to use S_New4 without the Updater. ( But your System must be Windows or Linux )
            const std::string VersionFileName = "";
            const std::string ProgrammFileName = "";
        #endif
    #endif

//Nicht x86 Architekture
#else
    //Raspberry Pi -> ARMv6 -> 32Bit
    #if defined(__ARM_ARCH_6__) && defined (__linux)
        const std::string VersionFileName =  std::string("Version-LIN-ARMv6.txt");
        const std::string ProgrammFileName =  std::string("S_New4-LIN-ARMv6");
    #else
        #error Falsche Architektur: Der Updater Fuktion wird nicht Funktionieren! Remove this Line in the Code to use S_New4 without the Updater. ( But your System must be Windows or Linux )
        const std::string VersionFileName = "";
        const std::string ProgrammFileName = "";
    #endif
#endif




    std::string name,
                accountFilePath = "",
                accountNumberPath= "",
                cookieFilePath  = "",
                serienListPath = "",

        lastUpdateDateFilePath = "",
        lastProgrammUpdateDateFilePath = "",


        configDir="",
        cacheDir="",
        logFilePath="",

        defaultsFilePath = "",
        proxy_ip = "127.0.0.1",
        languages = "GerDub,GerSub,Eng,",
        genaueHoster = "",
        version = VERSION,
        defaultFileVersion= DEFAULT_FILE_VERSION,
        default_checkPath = "",
        default_Searchmuster = "S%Staffel%E%Folge%",
        argv0,
        downloadCoverPfad;

    std::vector<std::string> outputFilePaths;


    Modus modus = Modus::EXIT;
    bool colorless = false,
         debugMode = false,
         search_IgnoreUpperLower = true,
         search_wantUpdate = false,
         search_show_othernames = false,
         askForEveryDir = true,
         skipEpisodenNameOutput = false,
        showLastUpdate = false,
        no_log = false;

    int startEpisode = 1,
        stopEpisode = 0,
        startSeason = 1,
        stopSeason = 0,
        proxy_port = 9050,
        default_maxDirs = 20,
        updateWarningDays = 10,

        programmUpdateWarningDays = 20;


    char pathSymbol = '/';
    char wrongPathSymbol = '\\';
    unsigned maxThreads = 0;

    enum COLOR {
        NO_COLOR = 0,
        Black = 30,
        Dark_Gray = 90,
        Red = 31,
        Light_Red = 91,
        Green = 32,
        Light_Green = 92,
        Brown_Orange = 33,
        Yellow = 93,
        Blue = 34,
        Light_Blue = 94,
        Purple = 35,
        Light_Purple = 95,
        Cyan = 36,
        Light_Cyan = 96,
        Light_Gray = 37,
        White = 97

    };
    std::string setPColor(const COLOR &color) {
        return ( (colorless) ? "" : "\033[" + std::to_string(color) +"m" );
    }
    std::string resetPColor() {
        return ( (colorless) ? "" : "\033[0m" );
    }


};



std::string replace(std::string str, std::string substr1, std::string substr2);

int manageParameter(Settings &settings, int argc, char ** argv);
int loadDefaulOptions(Settings & settings);
std::vector<std::string> compare(std::string All_Options_with_komma_between, std::string input);
bool isSame(char ** argv, std::string FunktionName);
bool isNumber(std::string number);

int setPaths(Settings &settings);

bool fileExists (const std::string& name);
bool dirExists(std::string dir);
bool nothingExists(std::string path);

bool createDirIsOk(std::string path);
bool makePathIsOk(std::string path);
bool removeDirIsOk(std::string path, Settings *settings, bool askForDelete);

int unterOption_help(Settings &settings);
void unterOption_printVersion(Settings &settings);

int unterOption_default(Settings * settings, int argc, char **argv);
void unterOption_default_help(std::string programName);

int unterOption_url(Settings * settings, int argc, char **argv);
void unterOption_url_help(std::string programName);

int unterOption_search(Settings * settings, int argc, char **argv);
void unterOption_search_help(std::string programName);

int unterOption_info(Settings * settings, int argc, char **argv);
void unterOption_info_help(std::string programName);

void unterOption_clean(Settings * settings, int argc, char **argv);

int unterOption_printJD2_renameSkript(Settings * settings, int, char **);
void unterOption_printJD2_help(std::string programName);


int unterOption_news(Settings * settings, int argc, char **argv);
void unterOption_news_help(std::string programName);

int unterOption_update(Settings * settings, int argc, char **argv);
void unterOption_update_help(std::string programName);

int unterOption_RemoveSettings_or_CacheDir(Settings * settings, int argc, char **argv);
void unterOption_RemoveSettings_or_CacheDire_help(std::string programName);

int unterOption_printLogFile(Settings * settings, int argc, char **argv);
void unterOption_printLogFile(std::string programName);

int unterOption_popular(Settings * settings, int argc, char **argv);
void unterOption_popular_help(std::string programName);




int setS5ProxytoSettings(Settings &settings, std::string optarg);
int setUpInternetPages(Settings &settings, std::string optarg);














#endif // PARAMETERMANAGER_H
