#include "parameterManager.h"

int setPaths(Settings &settings)
{
    //Path settings
    std::string CacheDir, SettingsDir;

#ifdef __linux__
    CacheDir = std::string(getenv("HOME")) + "/.cache/S_New4/";
    SettingsDir = std::string( getenv("HOME") ) + "/.config/S_New4/";
    settings.pathSymbol = '/';
    settings.wrongPathSymbol = '\\';
#endif
#ifdef _WIN32
    CacheDir = std::string(getenv("LOCALAPPDATA")) + "\\S_New4\\"; // C:\Users\{username}\AppData\Local
    SettingsDir = std::string( getenv("APPDATA") ) + "\\S_New4\\"; // C:\Users\{username}\AppData\Roaming
    settings.pathSymbol = '\\';
    settings.wrongPathSymbol = '/';
#endif

    if(CacheDir == "" || SettingsDir == "") {
        std::cout << " => Error: PfadVariablen sind nicht gesetzt." << std::endl;
        return -1;

    } else if(!dirExists(CacheDir)) {
        if(!makePathIsOk(CacheDir)) {
            std::cout << " => Error: Konnte Ordner nicht erstellen: " << CacheDir << std::endl;
            return -1;
        } else
            std::cout <<  "  > Erfolgreich Ordner '" << CacheDir << "' erstellt." << std::endl;

    } if(!dirExists(SettingsDir)) {
        if(!makePathIsOk(SettingsDir)) {
            std::cout << " => Error: Konnte Ordner nicht erstellen: " << SettingsDir << std::endl;
            return -1;
        } else
            std::cout <<  "  > Erfolgreich Ordner '" << SettingsDir << "' erstellt." << std::endl;
    }

    settings.cookieFilePath = CacheDir + "S_New4_cookies";
    settings.accountNumberPath = CacheDir + "Account_Number";
    settings.lastUpdateDateFilePath = CacheDir + "LastUpdateDate";
    settings.logFilePath = CacheDir + "LogFile";

    settings.lastProgrammUpdateDateFilePath = CacheDir + "LastProgrammUpdateDate";

    settings.accountFilePath = SettingsDir + "Accounts";
    settings.serienListPath = SettingsDir + "SerienListe";
    settings.defaultsFilePath = SettingsDir + "Defaults";

    settings.cacheDir = CacheDir;
    settings.configDir = SettingsDir;


    return 0;
}

int manageParameter(Settings &settings, int argc, char **argv)
{
    if(argv[0])
        settings.argv0 = argv[0];

    //Path settings
    if(setPaths(settings) != 0) {
        if(settings.debugMode)
            std::cerr << ">>> Debug In " << __FUNCTION__ << ": setPaths f() failed." << std::endl;
        return -1;

    } else if(loadDefaulOptions(settings) != 0) {
        if(settings.debugMode)
            std::cerr << ">>> Debug In " << __FUNCTION__ << ": loadDefaulOptions f() failed." << std::endl;
        return 28;

    } else if(argc < 2) {
        std::cout << " => Error: Keine Unteroption angegeben." << std::endl;
        std::cout << "Aufruf: " << settings.programName << " [Unteroption] [PARAMETER]" << std::endl;
        std::cout << "\"" << settings.programName << " --help\" liefert weitere Informationen." << std::endl;
        return 1;
    }

    //LogCommand...
    Logger logger(settings.logFilePath);
    std::string command;
    for (int i = 0; i < argc; ++i)
        if(argv[i])
            command += std::string(argv[i]) + " ";
    if(command.length() > 0)
        command.pop_back();
    logger.logCommandLine(command);

    //Find out right subProgramm

    std::vector<std::string> res = compare("help\n--help\ndefault\nurl\n--version\nsearch\ninfo\nclean\nnews\n--update\n--remove\nlog\nprintjdscript", argv[1]);
    if(res.size() != 1) {
        if(res.size() == 0)
            std::cout << " => Error: Keine Unteroption für " << argv[1] << " gefunden." << std::endl;
        else if(res.size() > 1) {
            std::cout << " => Error: Mehrere Unteroptionen für '" << argv[1] << "' gefunden:" << std::endl;
            for (auto &e : res)
                std::cout << "  > '" << argv[1] << "' ?= '" << e << "'" << std::endl;
        }
        std::cout << "Aufruf: " << settings.programName << " [Unteroption] [PARAMETER]" << std::endl;
        std::cout << "\"" << settings.programName << " --help\" liefert weitere Informationen." << std::endl;
        return 2;
    }
    res.clear();


    if(isSame(argv, "--help") || isSame(argv, "help")) {
        return unterOption_help(settings);

    } else if (isSame(argv, "default")) {
        return unterOption_default(&settings, argc, argv);

    } else if (isSame(argv, "url")) {
        return unterOption_url(&settings, argc, argv);

    } else if (isSame(argv, "--version")) {
        unterOption_printVersion(settings);
        return -1;

    } else if (isSame(argv, "search")) {
        return unterOption_search(&settings, argc, argv);

    } else if (isSame(argv, "info")) {
        return unterOption_info(&settings, argc, argv);

    } else if (isSame(argv, "clean")) {
        unterOption_clean(&settings, argc, argv);
        return -1;

    } else if (isSame(argv, "news")) {
        return unterOption_news(&settings, argc, argv);

    } else if (isSame(argv, "--update")) {
        argv[1][0] = '\0';
        return unterOption_update(&settings, argc, argv);

    } else if (isSame(argv, "--remove")) {
        return unterOption_RemoveSettings_or_CacheDir(&settings, argc, argv);

    } else if (isSame(argv, "log")) {
        if(unterOption_printLogFile(&settings, argc, argv) != -1)
            return 49;
        logger.logCommandLine(command);
        return -1;

    } else if (isSame(argv, "printjdscript")) {
        return unterOption_printJD2_renameSkript(&settings,argc, argv);

    } else {
        std::cout << " => Error: Invalid option '" << argv[1] << "', but not detected in compare-Function" << std::endl;
        return 3;
    }
}

void unterOption_printVersion(Settings &settings)
{
    std::cout << "S_New4-Programminformationen:" << std::endl
              << " > Build-Datum: \t\t" << __DATE__  << std::endl
              << " > Build-Uhrzeit: \t\t" << __TIME__ << std::endl
              << " > Program Version: \t\t" << settings.version << std::endl
              << " > Defaults Datei Version: \t" << settings.defaultFileVersion << std::endl

             #ifdef __MINGW_GCC_VERSION
              << " > MINGW GCC Version: \t" <<__GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ << std::endl
             #endif

              << " > Curl Version: \t\t" << PageManager::getCurlVersion() << std::endl

              << " > C++ Standart: \t\t";
    if(__cplusplus == 1) std::cout << "C++_Pre_C++98" << std::endl;
    else if (__cplusplus == 199711) std::cout << "C++98" << std::endl;
    else if (__cplusplus == 201103) std::cout << "C++11" << std::endl;
    else if (__cplusplus == 201402) std::cout << "C++14" << std::endl;
    else if (__cplusplus == 201703) std::cout << "C++17" << std::endl;
    else  std::cout << "C++_Newer_C++17" << std::endl;
    std::cout << " > Bit Version: \t\tx" << sizeof (void *) * 8 << "" << std::endl;
}

int loadDefaulOptions(Settings &settings)
{
    std::fstream ifs(settings.defaultsFilePath);
    if(!ifs.is_open()) {
        std::ofstream ofs(settings.defaultsFilePath);
        if(!ofs.is_open()) {
            perror((" => Error: Konnte Defaults-Datei nicht aufmachen: " + settings.defaultsFilePath).c_str());
            return 89;
        } else {
            std::cout << " => Erstelle Defaults-Datei: " << settings.defaultsFilePath << std::endl;
            ofs << "# -> Mit # kann man eine Zeile deaktivieren." << std::endl;
            ofs << "DefaultFileVersion="<< settings.defaultFileVersion << std::endl << std::endl;

            ofs << "#" << std::endl << "# -> Globale Einstellungen:" << std::endl << "#" << std::endl << std::endl;

            ofs << "# -> Einstellung gleicht dem Parameter -d, --debug-mode:" << std::endl;
            ofs << "#DebugModus=false" << std::endl << std::endl;

            ofs << "# -> Einstellung gleicht dem Parameter -p, --socks5-proxy:" << std::endl;
            ofs << "#    Verwende den Port 0 um keinen Proxy zu verwenden." << std::endl;
            ofs << "#Socks5Proxy=127.0.0.1:9050" << std::endl << std::endl;

            ofs << "# -> Einstellung gleicht dem Parameter -c, --colorless:" << std::endl;
            ofs << "#FarbloseAusgabe=false" << std::endl << std::endl;

            ofs << "# -> Einstellung gleicht dem Parameter -o [Pfad], --output-file," << std::endl;
            ofs << "#    falls dieser in der ausgeführeten Unterfunktion vorhanden ist:" << std::endl;
            ofs << "#    Hier auch mehrere Pfade Möglich..:" << std::endl;
            ofs << "#OutputFile=/tmp/a" << std::endl;
            ofs << "#OutputFile=/tmp/b" << std::endl;
            ofs << "# -> Log-to-LogFile: Speichere Ausgabe im LogFile - LogFile u.a. beim" << std::endl;
            ofs << "#    JD2-Renamer Skript nötig. Auch anderer Pfad möglich." << std::endl;
            ofs << "OutputFile=" << settings.logFilePath << std::endl << std::endl;

            ofs << "# -> Standart Wert für Parameter: -i, --internet-pages:" << std::endl;
            ofs << "# -> Internetseiten, auf denen die die Serie gesucht wird. " << std::endl;
            ofs << "#    (anicloud.ion/serienstream.sx) - Der Priorität nach angeben!" << std::endl;
            ofs << "#    Kombinierbar mit -f - Verwende erste Seite" << std::endl;
            ofs << "#    Unterstützte Seiten:" << std::endl;
            ofs << "#      s.to, 190.115.18.20, anicloud.io, serienstream.to, serien.cam, all" << std::endl;
            ofs << "Internetseiten=AniWorld.to,serienstream.to" << std::endl  << std::endl;

            ofs << "# -> Standart Wert für Parameter: -f, --use-first:" << std::endl;
            ofs << "# -> Benutze sofort die erste Seite, wenn die Serie dort existiert." << std::endl;
            ofs << "#    Wenn deaktiviert, manuelle auswahl der Seiten nötig!" << std::endl;
            ofs << "#UseFirstPage=true" <<  std::endl  << std::endl;

            ofs << "# -> Mit 0 Können Sie die Warnung für veraltete Suchlisten deaktivieren:" << std::endl;
            ofs << "#search_UpdateWarnungNachTagen=10" << std::endl << std::endl;

            ofs << "# -> Mit 0 Können Sie die Warnung für nötige Updateüberprüfungen deaktivieren:" << std::endl;
            ofs << "#search_ProgrammUpdateWarnungNachTagen=10" << std::endl << std::endl;



            ofs << "#" << std::endl << "# -> Einstellungen für default Modus:" << std::endl << "#" << std::endl << std::endl;

            ofs << "# -> Standart Wert für Parameter: -g, --genaue-hoster:" << std::endl;
            ofs << "default_GenaueHoster=UpStream,Vidoza,GoUnlimited" << std::endl << std::endl;

            ofs << "# -> Standart Wert für Parameter: -l, --languages:" << std::endl;
            ofs << "#default_Sprachen=GerDub,GerSub,Eng" << std::endl << std::endl;

            ofs << "# -> Standart Wert für Parameter: -m, --check-muster:" << std::endl;
            ofs << "#default_CheckSuchMuster=S%Staffel%E%Folge%" << std::endl << std::endl;

            ofs << "# -> Standart Wert für Parameter: -D, --check-max-dirs:" << std::endl;
            ofs << "#default_CheckMaxDirs=20" << std::endl << std::endl;

            ofs << "# -> Standart Wert für Parameter: -t, --threads:" << std::endl;
            ofs << "default_maxThreads=3" << std::endl << std::endl;

            ofs << "#" << std::endl << "# -> Einstellungen für search Modus:" << std::endl << "#" << std::endl << std::endl;

            ofs << "# -> Standart Wert für Parameter: -e, --exactly-writing:" << std::endl;
            ofs << "#search-AchteAufGroßUndKleinschreibung=false" << std::endl << std::endl;


            ofs << "# -> Aktiviert werden bei der Suche sämtliche Namen der Serie angezeigt." << std::endl;
            ofs << "#    Bei Animes kann das zu Mehrzeiligen ausgaben pro Serie führen!" << std::endl;
            ofs << "#search-showAllNames=false" << std::endl << std::endl;



            ofs.close();
        }
        ifs.open(settings.defaultsFilePath);
        if(!ifs.is_open()) {
            perror((" => Error: Konnte Defaults-Datei nach dem erstellen nicht aufmachen: " + settings.defaultsFilePath).c_str());
            return 97;
        }
    }

    std::string line;
    while (std::getline(ifs, line).good()) {
        if(line.find("#") != std::string::npos || line == "")
            continue;
        else if ( line.find("=") == std::string::npos ) {
            std::cout << " => Warnung: Bitte Info-Texte mit '#' am Anfang: Ungültige Option '" << line << "'." << std::endl;
            continue;
        }

        //extrahiere einstellung und wert aus Zeile:
        std::string what = line.substr(0, line.find("=")),
                    data = line.substr(line.find("=") + 1, line.length() - line.find("=") -1);

        if(what == "") {
            continue;

        } else if (what == "Socks5Proxy") {
            if(setS5ProxytoSettings(settings, data) != 0)
                return 2;

        } else if (what == "DefaultFileVersion") {
            if(data != settings.defaultFileVersion)
                std::cout << " => Warnung: Veraltetes Defaults-File. Löschen sie die Datei, um die neuste Version zu bekommen." << std::endl;

        } else if (what == "DebugModus") {
            if(data == "true")
                settings.debugMode=true;
            else if (data == "false")
                settings.debugMode=false;
            else {
                std::cout << " => Error_Defaults: DebugModus: Ungültiger Wert für 'true/false': " << data << std::endl;
                return 161;
            }
            if(settings.debugMode)
                std::cout << "  > Defaults: DebugMode: true" << std::endl;

        } else if (what == "default_GenaueHoster") {
            settings.genaueHoster=data;
            if(settings.debugMode)
                std::cout << "  > Defaults: GenaueHoster: " << settings.genaueHoster << std::endl;

        } else if (what == "default_Sprachen") {
            settings.languages=data;
            if(settings.debugMode)
                std::cout << "  > Defaults: Sprachen: " << settings.languages << std::endl;

        } else if (what == "default_CheckSuchMuster") {
            settings.default_Searchmuster=data;
            if(settings.debugMode)
                std::cout << "  > Defaults: SuchMuster: " << settings.default_Searchmuster << std::endl;

        } else if (what == "default_CheckMaxDirs") {
            settings.default_maxDirs = atoi(data.c_str());
            if(!isNumber(data) ) {
                std::cout << " => Error_Defaults: default_CheckMaxDirs: Ungültige Zahl: " << data << std::endl;
                return 18;
            }
            if(settings.debugMode)
                std::cout << "  > Defaults: default_CheckMaxDirs: " << settings.default_maxDirs << std::endl;


        } else if (what == "default_maxThreads") {
            settings.maxThreads = static_cast<unsigned>(atoi(data.c_str()));
            if(!isNumber(data) ) {
                std::cout << " => Error_Defaults: Thread-Max Ungültige Zahl: " << data << std::endl;
                return 18;
            } else if (settings.maxThreads > 4) {
                std::cout << " => Error_Defaults: Thread-Max: Zahl größer 4: " << data << std::endl;
                return 19;
            }
            if(settings.debugMode)
                std::cout << "  > Defaults: MaxThreads: " << settings.maxThreads << std::endl;

        } else if (what == "FarbloseAusgabe") {
            if(data == "true")
                settings.colorless=true;
            else if (data == "false")
                settings.colorless=false;
            else {
                std::cout << " => Error_Defaults: FarbloseAusgabe: Ungültiger Wert für 'true/false': " << data << std::endl;
                return 207;
            }
            if(settings.debugMode)
                std::cout << "  > Defaults: FarbloseAusgabe: " << settings.colorless << std::endl;

        } else if (what == "search-AchteAufGroßUndKleinschreibung") {
            if(data == "true")
                settings.search_IgnoreUpperLower=false;
            else if (data == "false")
                settings.search_IgnoreUpperLower=true;
            else {
                std::cout << " => Error_Defaults: search-AchteAufGroßUndKleinschreibung: Ungültiger Wert für 'true/false': " << data << std::endl;
                return 227;
            }
            if(settings.debugMode)
                std::cout << "  > Defaults: search-AchteAufGroßUndKleinschreibung: " << settings.search_IgnoreUpperLower << std::endl;

        } else if (what == "OutputFile") {
            settings.outputFilePaths.push_back(data);
            if(settings.debugMode)
                std::cout << "  > Defaults: OutputFile: " << settings.outputFilePaths.back() << std::endl;

        } else if (what == "search_UpdateWarnungNachTagen") {
            if(!isNumber(data)) {
                std::cout << " Error_Defaults: search_UpdateWarnungNachTagen: Wert ist keine Zahl." << std::endl;
                return 228;
            } else {
                settings.updateWarningDays = atoi(data.c_str());
            }
            if(settings.debugMode)
                std::cout << "  > Defaults: search_UpdateWarnungNachTagen: " << settings.updateWarningDays << std::endl;

        } else if (what == "Internetseiten") {
            if(setUpInternetPages(settings, data) != 0)
                return 1233;

        } else if (what == "UseFirstPage") {
            if(data == "true")
                settings.useFirstPage=true;
            else if (data == "false")
                settings.useFirstPage=false;
            else {
                std::cout << " => Error_Defaults: sUseFirstPage: Ungültiger Wert für 'true/false': " << data << std::endl;
                return 245;
            }
            if(settings.debugMode)
                std::cout << "  > Defaults: UseFirstPage: " << settings.useFirstPage << std::endl;

        } else if (what == "search-showAllNames") {

            if(data == "true")
                settings.search_show_othernames=true;
            else if (data == "false")
                settings.search_show_othernames=false;
            else {
                std::cout << " => Error_Defaults: search-showAllNames: Ungültiger Wert für 'true/false': " << data << std::endl;
                return 2487;
            }
            if(settings.debugMode)
                std::cout << "  > Defaults: search-showAllNames: " << settings.search_show_othernames << std::endl;

        } else if (what == "search_ProgrammUpdateWarnungNachTagen") {
            if(!isNumber(data)) {
                std::cout << " Error_Defaults: search_ProgrammUpdateWarnungNachTagen: Wert ist keine Zahl." << std::endl;
                return 228;
            } else {
                settings.programmUpdateWarningDays = atoi(data.c_str());
            }
            if(settings.debugMode)
                std::cout << "  > Defaults: search_ProgrammUpdateWarnungNachTagen: " << settings.programmUpdateWarningDays << std::endl;

        } else {
            std::cout << " => Warnung: Unbekannte Default-Option: '" << what << "'." << std::endl;
        }
    }

    ifs.close();
    return 0;
}

int unterOption_help(Settings &settings)
{
    std::cout << "Aufruf: " << settings.programName << " [Unteroption] [PARAMETER]..." << std::endl << std::endl;
    std::cout << "Beschreibung:" << std::endl
              << "      -> Mit diesem Programm kann man die Download-Urls" << std::endl
              << "         oder Informationen von Serien bekommen." << std::endl
              << "      -> Mit diesem Programm kann man Redirect-Links von" << std::endl
              << "         serienstream.sx und anicloud.io umwandeln." << std::endl
              << std::endl;

    std::cout << "Unteroptionen:" << std::endl
              << "\t\"--help\" \tGibt dieses Helpmenue aus." << std::endl
              << "\t\"--version\"\tGibt die Version des Programmes aus." << std::endl
              << "\t\"--update\"\tModus um das Programm zu aktualisieren." << std::endl
              << "\t            \tUpdater funktioniert nur bei: Windows/Linux -" << std::endl
              << "\t            \tx86 Architekutur - 64 Bit Systemen und ARM v6 Syst." << std::endl
              << "\t\"--remove\"\tModus um Ordner mit Einstellungen/" << std::endl
              << "\t            \tZwischengespeicherte-Dateien zu löschen." << std::endl
              << "\t\"url\"\t\tModus um eigene Redirect-Links umzuwandeln." << std::endl
              << "\t\"default\"\tModus um Links von Serien zu bekommen." << std::endl
              << "\t\"search\"\tModus um Serien zu suchen." << std::endl
              << "\t\"info\"\t\tModus um Infos einer Serien zu bekommen." << std::endl
              << "\t\"news\"\t\tModus um neusten 75 Folgen zu sehen." << std::endl
              << "\t\"clean\"\t\tModus um Cookie-Files zu löschen." << std::endl
              << "\t\"log\"\t\tModus um Log Datei zu sehen / leeren." << std::endl
              << std::endl;

    std::cout << "Verzeichnisse:" << std::endl
              << "\tOrdner zum zwischenspeichern der Cookies, AccountNummer" << std::endl
              << "\tund des letzten Update Datums:" << std::endl
              << "   =>      > '" << std::string(settings.cookieFilePath).erase(settings.cookieFilePath.find_last_of(settings.pathSymbol) + 1) << "'" << std::endl
              << "\tOrdner zum speichern der Accounts, Default-Einstellungen" << std::endl
              << "\tund der Serienliste:" << std::endl
              << "   =>      > '" << std::string(settings.defaultsFilePath).erase(settings.defaultsFilePath.find_last_of(settings.pathSymbol) + 1) << "'" << std::endl;

    return -1;
}


int unterOption_default(Settings *settings, int argc, char ** argv)
{
    settings->modus = Modus::DEFAULT_MODUS;

    int c = 0;
    const option long_opts[] = {
        {"socks5-proxy", required_argument, nullptr, 'p'},
        {"genaue-hoster", required_argument, nullptr, 'g'},
        {"languages", required_argument, nullptr, 'l'},
        {"output-file", required_argument, nullptr, 'o'},

        {"start-episode", required_argument, nullptr, 'e'},
        {"stop-episode", required_argument, nullptr, 'E'},
        {"start-season", required_argument, nullptr, 's'},
        {"stop-season", required_argument, nullptr, 'S'},

        {"check", required_argument, nullptr, 'C'},
        {"check-muster", required_argument, nullptr, 'm'},
        {"check-max-dirs", required_argument, nullptr, 'D'},

        {"threads", required_argument, nullptr, 't'},
        {"internet-pages", required_argument, nullptr, 'i'},

        {"help", no_argument, nullptr, 'h'},
        {"colorless", no_argument, nullptr, 'c'},
        {"debug-mode", no_argument, nullptr, 'd'},
        {"use-first-page", no_argument, nullptr, 'f'},

        {nullptr, no_argument, nullptr, 0}

    };


    while( ( c = getopt_long (argc, argv, "p:g:l:o:e:E:s:S:C:m:D:t:i:fhcd", long_opts, nullptr) ) != -1 ) {
        switch(c) {
            case 'p':
                if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0)
                    return 2;
                break;
            case 'g':
                if(optarg)
                    settings->genaueHoster =+ optarg + std::string(",");
                if(settings->debugMode)
                    std::cout << "Hosterreihenfolge: " << settings->genaueHoster << std::endl;
                break;
            case 'l':
                if(optarg)
                settings->languages =+ optarg + std::string(",");
                if(settings->debugMode)
                    std::cout << "Sprachenreihenfolge: " << settings->languages << std::endl;
                break;
            case 'o':
                if(optarg)
                    settings->outputFilePaths.push_back(optarg);
                if(settings->debugMode)
                    std::cout << "Pfad zu Output-Datei: " << settings->outputFilePaths.back() << std::endl;
                break;

            case 'e':
                if(!optarg)
                    break;
                settings->startEpisode = atoi(optarg);
                if (!isNumber(optarg)) {
                    std::cout << " => Error: -e [Folge]: '" << optarg << "' ist keine Zahl." << std::endl;
                    return 11;
                } else if (settings->startEpisode <= 0) {
                    std::cout << " => Error: -e [Folge]: StartEpisode " << settings->startEpisode << " ist kleiner gleich 0." << std::endl;
                    return 13;
                }
                if(settings->debugMode)
                    std::cout << "StartEpisode: " << settings->startEpisode << std::endl;
                break;
            case 'E':
                if(!optarg)
                    break;
                settings->stopEpisode = atoi(optarg);
                if (!isNumber(optarg)) {
                    std::cout << " => Error: -E [Folge]: '" << optarg << "' ist keine Zahl." << std::endl;
                    return 14;
                } else if (settings->debugMode)
                    std::cout << "StopEpisode: " << settings->stopEpisode << std::endl;
                break;
            case 's':
                if(!optarg)
                    break;
                settings->startSeason = atoi(optarg);
                if (!isNumber(optarg)) {
                    std::cout << " => Error: -s [Staffel]: '" << optarg << "' ist keine Zahl." << std::endl;
                    return 15;
                } else if (settings->startSeason < 0) {
                    std::cout << " => Error: -s [Staffel]: StartStaffel " << settings->startSeason << " ist kleiner 0." << std::endl;
                    return 17;
                } else if(settings->debugMode)
                    std::cout << "StartStaffel: " << settings->startSeason << std::endl;
                break;
            case 'S':
                if(!optarg)
                    break;
                settings->stopSeason = atoi(optarg);
                if (!isNumber(optarg)) {
                    std::cout << " => Error: -S [Staffel]: '" << optarg << "' ist keine Zahl." << std::endl;
                    return 18;
                } else if(settings->debugMode)
                    std::cout << "StopSeason: " << settings->stopSeason << std::endl;
                break;
            case 'm':
                if(optarg)
                    settings->default_Searchmuster = optarg;
                if(settings->debugMode)
                    std::cout << " SearchMuster: " << settings->default_Searchmuster << std::endl;
                break;
            case 'D':
                if(!optarg)
                    break;
                settings->default_maxDirs = atoi(optarg);
                if(!isNumber(optarg)) {
                    std::cout << " => Error: [-D]: Ungültige Zahl: " << optarg << std::endl;
                    return 18;
                }
                if(settings->debugMode)
                    std::cout << "CheckMaxDirs: " << settings->default_maxDirs << std::endl;

                break;
            case 't':
                if(!optarg)
                    break;
                settings->maxThreads = static_cast<unsigned>(atoi(optarg));
                if(!isNumber(optarg)) {
                    std::cout << " => Error: [-t]: Thread-Max: Ungültige Zahl: " << optarg << std::endl;
                    return 18;
                } else if (settings->maxThreads > 4 && !settings->debugMode) {
                    std::cout << " => Error: [-t]: Thread-Max: Zahl ist größer 4: " << optarg << std::endl;
                    return 19;
                }
                if(settings->debugMode)
                    std::cout << "MaxThreads: " << settings->maxThreads << std::endl;

                break;

            case 'i':
                if(!optarg)
                    break;
                if(setUpInternetPages(*settings, optarg) != 0)
                    return 4356;

                break;
            case 'f':
                settings->useFirstPage = true;
                if(settings->debugMode)
                    std::cout << "useFirstPage: " << settings->useFirstPage << std::endl;
                break;
            case 'C':
                if(!optarg)
                    break;
                settings->default_checkPath = optarg;
                if(settings->debugMode)
                    std::cout << "To check Dir/File: " << settings->default_checkPath << std::endl;
                break;
            case 'c':
                settings->colorless = true;
                if(settings->debugMode)
                    std::cout << "Farblos: true" << std::endl;
                if(argc > optind)
                    if(argv[optind][0] != '-' && std::string(argv[optind]).find(settings->pathSymbol) != std::string::npos) {
                        std::cout << " => Upps: Hast du -c (--colorless) mit -C (--check-dir) verwechselt?" << std::endl
                                  << "    (Hat \"Argument\" mit \""<< settings->pathSymbol << "\": '-c " << std::string(argv[optind]) << "')." << std::endl;
                        return -1;
                    }
                break;
            case 'd':
                settings->debugMode = true;
                if(settings->debugMode)
                    std::cout << "Debug Modus: true" << std::endl;
                break;
            case 'h':
                unterOption_default_help(settings->programName);
                return -1;
            default:
                std::cout << "Aufruf: " << settings->programName << " default [OPTION]... [NAME]..." << std::endl;
                std::cout << "\"" << settings->programName << " default --help\" liefert weitere Informationen." << std::endl;
                return -1;
        }
    }
    //Alle nicht verwendeten Parameter == Name
    while (optind < argc) {
        if(argv[optind][0]) {
            settings->name.append(argv[optind++]).append(" "); // optind++ gives the value before ++ back
        } else
            ++optind;
    }

    if(settings->name.length() > 0)
        settings->name.pop_back();
    if(settings->debugMode) {
        std::cout << "Name: " << settings->name << std::endl;
        std::cout << "Modus: DEFAULT_MODUS" << std::endl;
    }

    return 0;
}

void unterOption_default_help(std::string programName)
{
    std::cout << "Aufruf: " << programName << " default [OPTION]... [NAME]" << std::endl << std::endl;

    std::cout << "Beschreibung:" << std::endl
              << "    Mit dieser Unterfunktion kann man die Downloadlinks von Serien bekommen." << std::endl << std::endl;


    std::cout << "INTERNETSEITEN OPTIONEN:" << std::endl
              << "    -i [Url1,Url2], --internet-pages [Url1,Url2]" << std::endl
              << "          Mit dieser Option kann man die Seiten angeben, auf denen" << std::endl
              << "          nach Serien gesucht werden soll. (Nur Seiten aus Default Wert möglich)" << std::endl
              << "          Die Seiten Kommagetrennt nach Priorität angeben. (Höchste am Anfang)" << std::endl
              << "          Gut Kombinierbar mit --use-first-page kombenierbar!" << std::endl
              << "          Standart: AniWorld.to,serienstream.to" << std::endl
              << "    -f, --use-first-page" << std::endl
              << "          Mit dieser Option kann man festlegen, dass direkt die erste Seite," << std::endl
              << "          auf der die Serie vorhanden ist, verwendet wird. ( Reihenfolge der" << std::endl
              << "          Priorität nach; siehe -i, --internet-pages)" << std::endl
              << "          Ohne diesem Parameter ist eine manuelle auswahl nötig," << std::endl
              << "          wenn diese Serie auf mehreren Seiten existiert!"  << std::endl
              << "          Parameter kann auch im Default File als standart festgelegt werden!" << std::endl
              << "          Standartmäßig: Überprüfe alle Seiten"  << std::endl << std::endl
              << "HOSTER OPTIONEN:" << std::endl
              << "    -g [Hoster1,Hoster2,...], --genaue-hoster [Hoster1,Hoster2,...]" << std::endl
              << "          Mit dieser Option kann man die Hoster angeben, von denen" << std::endl
              << "          man die Downloadlinks will. Die Auswahl der Hoster geht" << std::endl
              << "          der Reihe nach: Der als erstes angegebene Hoster wird als" << std::endl
              << "          erstes verwendet, wenn er für die Folge vorhanden ist, sonst" << std::endl
              << "          versuche 2ten Hoster,..." << std::endl
              << "          Beachte verwendug mit -l: Die Reihenfolge ist:" << std::endl
              << "          1.Angegebene Sprache, 1. Angegebener Hoster; 1.Sprache, 2.Hoster,..." << std::endl
              << "          2.Sprache, 1.Hoster,..." << std::endl << std::endl
              << "    -l [GerDub/GerSub/Eng,...], --languages [GerDub/GerSub/Eng,...]" << std::endl
              << "          Mit dieser Option kann man die Sprachen angeben, von" << std::endl
              << "          denen man die Downloadlinks will. Die Beste als erstes" << std::endl
              << "          die 2t-Beste als 2tes,..." << std::endl
              << "          Standart: GerDub,GerSub,Eng" << std::endl << std::endl
              << "DURCHLAUF OPTIONEN:" << std::endl
              << "    -e [Folge], --start-episode [Folge]" << std::endl
              << "          Mit dieser Option kann man festlegen, mit welcher Folge" << std::endl
              << "          das Programm startet." << std::endl
              << "          Standart: 1" << std::endl
              << "    -s [Staffel], --start-season [Staffel]" << std::endl
              << "          Mit dieser Option kann man festlegen, mit welcher Staffel das" << std::endl
              << "          Programm startet. Verwende 0 um mit der letzten Staffel zu starten." << std::endl
              << "          Standart: 1" << std::endl << std::endl
              << "    -E [Folge], --stop-episode [Folge]" << std::endl
              << "          Mit dieser Option kann man festlegen, mit welcher Folge" << std::endl
              << "          das Programm stopt. Verwende 0 um die Option zu deaktiviern." << std::endl
              << "          Beachte:" << std::endl
              << "          -> Wenn -S nicht verwendet wird, stopt das Programm" << std::endl
              << "             sobald die angegebene Folge erreicht wurde." << std::endl
              << "          -> Wenn -S auch verwendet wird, stop das Programm" << std::endl
              << "             1. sobald die angegebene Folge und die angegebene Staffel erreicht" << std::endl
              << "                wurden," << std::endl
              << "             2. wenn die angegebene Staffel von -S vollendet wurde." << std::endl
              << "          Standert: 0" << std::endl << std::endl
              << "    -S [Staffel], --stop-season [Staffel]" << std::endl
              << "          Mit dieser Option kann man festlegen, mit welcher Staffel" << std::endl
              << "          das Programm stopt. Verwende 0 um die Option zu deaktivieren." << std::endl
              << "          Beachte verwendung mit -E." << std::endl
              << "          Standart: 0" << std::endl << std::endl
              << "SOCK5PROXY:" << std::endl
              << "    -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl
              << "          Mit dieser Option kann man den Socks5Proxy ändern." << std::endl
              << "          Port 0 um Proxy zu deaktivieren."  << std::endl
              << "          Standart: 127.0.0.1:9050" << std::endl << std::endl
              << "AUSGABE OPTIONEN:" << std::endl
              << "    -o [Pfad], --output-file [Pfad]" << std::endl
              << "          Mit diere Option kann man eine (nichtvorhandene) Text-Datei" << std::endl
              << "          angeben, inwelche die umgewandelten Redirect-Links geschrieben" << std::endl
              << "          werden. Beachte: Wenn die Datei von -C existiert, dann" << std::endl
              << "          schreibt das Programm kein 'Name: ...' in die Datei." << std::endl
              << "    -c, --colorless" << std::endl
              << "          Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl
              << "    -d, --debug-mode" << std::endl
              << "          Mit dieser Option kann man den Debug-Modus einschalten." << std::endl
              << "          Dabei werden vielmehr Infos ausgegeben." << std::endl << std::endl
              << "SELEKTOR OPTIONEN:" << std::endl
              << "    -C [PfadZuOrdner], --check [PfadZuOrdner]" << std::endl
              << "          Mit dieser Option kann man einen Ordner festlegen, in dem" << std::endl
              << "          und dessen Unterordnern ( Beachte -D ) das Programm erst" << std::endl
              << "          überprüft, ob eine Datei mit einem bestimmten Muster" << std::endl
              << "          ( Beachte -m ) vorkommt. Wenn diese vorkommt, wird die Folge" << std::endl
              << "          übersprungen." << std::endl << std::endl
              << "    -C [PfadZuTextDatei], --check [PfadZuTextDatei]" << std::endl
              << "          Mit dieser Option kann man eine Textdatei angeben, in der" << std::endl
              << "          bei jedem Durchlauf überprüft wird, ob ein bestimmtes Muster " << std::endl
              << "          vorkommt ( Beachte -m ). Wenn ja, wird die Folge übersprungen." << std::endl
              << "          Tipp: Mit -o zu der gleichen Datei kann verwendet werden, um" << std::endl
              << "                nur neue Folgen einer Serie zu downloaden." << std::endl
              << "          Beachte: Bei verwendung dieser Option, wird kein" << std::endl
              << "                   'Name: ...' in die Datei geschrieben, wenn die" << std::endl
              << "                   Datei beim überprüfen existiert." << std::endl << std::endl
              << "    -m [Muster], --check-muster [Muster]" << std::endl
              << "          Mit dieser Option kann man das Muster verändern, das bei" << std::endl
              << "          der Option -C verwendet wird." << std::endl
              << "          %Staffel% kann als Platzhalter für die Staffel im Durch-" << std::endl
              << "          lauf verwendet werde." << std::endl
              << "          %Folge% als Platzhalter für die jeweilige Folge." << std::endl
              << "          Beachte: Bei den Platzhaltern: 01,02,..,09,10,11,..." << std::endl
              << "          Standart: S%Staffel%E%Folge%" << std::endl << std::endl
              << "    -D [AnzahlAnOrdnern], --check-max-dirs [AnzahlAnOrdnern]" << std::endl
              << "          Mit dieser Option kann man die maximale Anzahl an Ordnern" << std::endl
              << "          angeben, die Durchsucht werden sollen." << std::endl
              << "          Standart: 20" << std::endl << std::endl
              << "MULTITHEADING:" << std::endl
              << "    -t [ThreadAnzahl], --threads [ThreadAnzahl]" << std::endl
              << "          Mit dieser Option kann man das Multihreading aktivieren." << std::endl
              << "          Das Programm startet dann für jede Folge einen neuen" << std::endl
              << "          Thread, bis die angegebene Anzahl an Threads erreicht" << std::endl
              << "          wurde. Dannm wartet es auf das Enden der Threads und" << std::endl
              << "          beginnt von vorne. Verwende 0 um das Multihreading zu" << std::endl
              << "          deaktivieren. Maximal 4 Threads. ( s.to hat bereits Ddos Schutz !!! )" << std::endl
              << "          Standart: 0" << std::endl << std::endl
              << "HELPMENUE:" << std::endl
              << "    -h, --help" << std::endl
              << "          Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl;
}


int unterOption_url(Settings *settings, int argc, char **argv)
{
    settings->modus = Modus::DIRECT_LINK_MODUS;

    int c = 0;
    const option long_opts[] = {
        {"socks5-proxy", required_argument, nullptr, 'p'},
        {"output-file", required_argument, nullptr, 'o'},
        {"standart-page", required_argument, nullptr, 's'},

        {"help", no_argument, nullptr, 'h'},
        {"colorless", no_argument, nullptr, 'c'},
        {"debug-mode", no_argument, nullptr, 'd'},
        {"use-first-page", no_argument, nullptr, 'f'},

        {nullptr, no_argument, nullptr, 0}

    };



    while( ( c = getopt_long (argc, argv, "p:o:s:fhcd", long_opts, nullptr) ) != -1 ) {
        switch(c) {
            case 'p':
                if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0)
                    return 2;
                break;
            case 'o':
                if(optarg)
                    settings->outputFilePaths.push_back(optarg);
                if(settings->debugMode)
                    std::cout << "Pfad zu Output-Datei: " << settings->outputFilePaths.back() << std::endl;
                break;
            case 'f':
                settings->useFirstPage = true;
                if(settings->debugMode)
                    std::cout << "useFirstPage: " << settings->useFirstPage << std::endl;
                break;
            case 'c':
                settings->colorless = true;
                if(settings->debugMode)
                    std::cout << "Farblos: true" << std::endl;
                break;
            case 's':
                if(!optarg)
                    break;
                for( auto &i : settings->pagesALL ) {
                    if( std::string(optarg) == i.url ) {
                        settings->direktLink_explizitPage = i;
                        if(settings->debugMode)
                            std::cout << "  > Defaults: Standart-Page-für-direkt-link-mode: " << i.url << std::endl;
                    }
                }
                break;
            case 'd':
                settings->debugMode = true;
                if(settings->debugMode)
                    std::cout << "Debug Modus: true" << std::endl;
                break;
            case 'h':
                unterOption_url_help(settings->programName);
                return -1;
            default:
                std::cout << "Aufruf: " << settings->programName << " url [OPTION]... [URL]..." << std::endl;
                std::cout << "\"" << settings->programName << " url --help\" liefert weitere Informationen." << std::endl;
                return 21;
        }
    }


    //Alle nicht verwendeten Parameter == Name
    while (optind < argc) {
        if(argv[optind][0]) {
            settings->name.append(argv[optind++]).append(",");
        } else
            ++optind;
    }

    if(settings->name.length() > 0)
        settings->name.pop_back();
    if(settings->debugMode) {
        std::cout << "Urls: " << settings->name << std::endl;
        std::cout << "Modus: DIRECT_LINK_MODUS" << std::endl;
    }

    return 0;
}

void unterOption_url_help(std::string programName)
{
    std::cout << "Aufruf: " << programName << " url [OPTION]... [URL]..." << std::endl << std::endl;

    std::cout << "Beschreibung:" << std::endl
              << "    Mit dieser Unterfunktion von " << programName << " können eigene" << std::endl
              << "    Redirect-Links umgewandelt werden. Beispiel:" << std::endl
              << "    https://serienstream.sx/redirect/44498xy -> https://vivolvox.xy/123xy" << std::endl
              << "    Der Link kann folgen Aussehen: {[*]serienstream.sx}/redirect/[*]." << std::endl
              << "    Standartwerte können im Defaultfile geändert werden." << std::endl << std::endl;

    std::cout << "INTERNETSEITEN OPTIONEN:" << std::endl
                  << "    -f, --use-first-page" << std::endl
                  << "          Mit dieser Option kann man festlegen, dass direkt die erste Seite," << std::endl
                  << "          auf der die Serie vorhanden ist, verwendet wird. ( Reihenfolge der" << std::endl
                  << "          Priorität nach; siehe -i, --internet-pages)" << std::endl
                  << "          Ohne diesem Parameter ist eine manuelle auswahl nötig," << std::endl
                  << "          wenn diese Serie auf mehreren Seiten existiert!"  << std::endl
                  << "          Parameter kann auch im Default File als standart festgelegt werden!" << std::endl
                  << "          Standart: Überprüfe alle Seiten"  << std::endl
                  << "     -s [url], --standart-page [url]" << std::endl
                  << "          Mit dieser Option kann man festlegen, welche Seite für unvollständige" << std::endl
                  << "          Redirect Links ( z.B. /redirect/xyz ) verwendet werden soll." << std::endl
                  << "          Default: deaktiviert" << std::endl << std::endl;
      std::cout << "OPTIONEN:" << std::endl
              << "    -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl
              << "          Mit dieser Option kann man den Socks5Proxy ändern." << std::endl
              << "          Port 0 um Proxy zu deaktivieren." << std::endl
              << "          Standart: 127.0.0.1:9050" << std::endl << std::endl
              << "    -o [Pfad], --output-file [Pfad]" << std::endl
              << "          Mit diere Option kann man ein (nichtvorhandenes) Text-Datei angeben," << std::endl
              << "          inwelches die umgewandelten Redirect-Links geschrieben werden." << std::endl << std::endl
              << "    -c, --colorless" << std::endl
              << "          Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl
              << "    -d, --debug-mode" << std::endl
              << "          Mit dieser Option kann man den Debug-Modus einschalten." << std::endl
              << "          Dabei werden vielmehr Infos ausgegeben." << std::endl << std::endl
              << "    -h, --help" << std::endl
              << "          Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl;
}


int unterOption_search(Settings *settings, int argc, char **argv)
{
    settings->modus = Modus::SEARCH_MODUS;

    int c = 0;
    const option long_opts[] = {
        {"socks5-proxy", required_argument, nullptr, 'p'},
        {"internet-pages", required_argument, nullptr, 'i'},

        {"show-all-names", no_argument, nullptr, 's'},
        {"help", no_argument, nullptr, 'h'},
        {"colorless", no_argument, nullptr, 'c'},
        {"debug-mode", no_argument, nullptr, 'd'},
        {"exactly-writing", no_argument, nullptr, 'e'},
        {"update", no_argument, nullptr, 'u'},
        {"last-update", no_argument, nullptr, 'l'},

        {nullptr, no_argument, nullptr, 0}

    };


    while( ( c = getopt_long (argc, argv, "p:i:shcdeul", long_opts, nullptr) ) != -1 ) {
        switch(c) {
            case 'p':
                if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0)
                    return 2;
                break;
            case 'i':
                if(!optarg)
                    break;
                if(setUpInternetPages(*settings, optarg) != 0)
                    return 4356;
                break;
            case 'h':
                unterOption_search_help(settings->programName);
                return -1;
            case 's':
                settings->search_show_othernames = true;
                if(settings->debugMode)
                    std::cout << "search_show_othernames: true" << std::endl;
                break;
            case 'c':
                settings->colorless = true;
                if(settings->debugMode)
                    std::cout << "Farblos: true" << std::endl;
                break;
            case 'd':
                settings->debugMode = true;
                if(settings->debugMode)
                    std::cout << "Debug Modus: true" << std::endl;
                break;
            case 'e':
                settings->search_IgnoreUpperLower = false;
                if(settings->debugMode)
                    std::cout << "Achte auf Groß und Kleinschreibung: true" << std::endl;
                break;
            case 'u':
                settings->search_wantUpdate = true;
                if(settings->debugMode)
                    std::cout << "Update die Liste: true" << std::endl;
                break;
            case 'l':
                settings->showLastUpdate = true;
                if(settings->debugMode)
                    std::cout << "showLastUpdate: true" << std::endl;
                break;
            default:
                std::cout << "Aufruf: " << settings->programName << " search [OPTION]... [NAME]..." << std::endl;
                std::cout << "\"" << settings->programName << " search --help\" liefert weitere Informationen." << std::endl;
                return 21;
        }
    }

    //Alle nicht verwendeten Parameter == Name
    while (optind < argc) {
        if(argv[optind][0]) {
            settings->name.append(argv[optind++]).append(" ");
        } else
            ++optind;
    }
    if(settings->name.length() > 0)
        settings->name.pop_back();
    if(settings->debugMode) {
        std::cout << "Name: " << settings->name << std::endl;
        std::cout << "Modus: Search_MODUS" << std::endl;
    }

    return 0;
}

void unterOption_search_help(std::string programName)
{
    std::cout << "Aufruf: " << programName << " search [OPTION]... [NAME]" << std::endl
              << "        " << programName << " search [OPTION]... [{-u, --update}&|/{-l, --last-update}]" << std::endl
              << "        " << programName << " search [OPTION]... [{-u, --update}&|/{-l, --last-update}] [Name]" << std::endl << std::endl;


    std::cout << "Beschreibung:" << std::endl
              << "    Mit dieser Unterfunktion des Programms kann man Serien auf serienstream.sx suchen." << std::endl
              << "    Tipp: Falls deine Serie nicht gefunden wird, entferne einen Teil" << std::endl
              << "          am Ende deines SuchNamens und wiederhole die Suche." << std::endl
              << "    Tipp: Wenn deine Serie sehr neu auf serienstream.sx ist, und deshalb nicht gefunden" << std::endl
              << "          wird, verwende die Option -u, um die Liste zu aktualisieren." << std::endl << std::endl;

    std::cout << "AKTUALISIERUNG:" << std::endl
              << "    -u, --update" << std::endl
              << "          Mit dieser Option wird die Liste der Serien, die bei der" << std::endl
              << "          Suche durchsucht wird, aktualisiert." << std::endl << std::endl;

    std::cout << "AKTUALISIERUNGSWARNUNG:" << std::endl
              << "    In der Defaults Datei findest du die Einstellung" << std::endl
              << "    'search_UpdateWarnungNachTagen' mit der du festlegen kannst," << std::endl
              << "    nach wie vielen Tagen du an das Updaten erinert wirst." << std::endl
              << "    Default: 10 Tage." << std::endl << std::endl;

    std::cout << "INTERNETSEITEN OPTIONEN:" << std::endl
                  << "    -i [Url1,Url2], --internet-pages [Url1,Url2]" << std::endl
                  << "          Mit dieser Option kann man die Seiten angeben, auf denen" << std::endl
                  << "          nach Serien gesucht werden soll. (Nur Seiten aus Default Wert möglich)" << std::endl
                  << "          Die Seiten Kommagetrennt nach Priorität angeben. (Höchste am Anfang)" << std::endl
                  << "          Das Aktualisieren der Liste kann damit nicht beeinflusst werden." << std::endl
                  << "          Standart: AniWorld.to,serienstream.to" << std::endl << std::endl;

    std::cout << "OPTIONEN:" << std::endl
              << "    -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl
              << "          Mit dieser Option kann man den Socks5Proxy ändern." << std::endl
              << "          Port 0 um Proxy zu deaktivieren." << std::endl
              << "          Standart: 127.0.0.1:9050" << std::endl << std::endl
              << "    -e, --exactly-writing" << std::endl
              << "          Mit dieser Option achtet das Programm auf Groß- und Kleinschreibung." << std::endl << std::endl
              << "    -l, --last-update" << std::endl
              << "          Mit dieser Option wird ausgegeben, vor wie vielen Tagen die" << std::endl
              << "          Serienliste zuletzt aktualisiert wurde." << std::endl << std::endl
              << "    -c, --colorless" << std::endl
              << "          Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl
              << "    -s, --show-all-names" << std::endl
              << "          Mit dieser Option werden alle Namen einer Serie ausgegeben." << std::endl
              << "          Vorsicht bei Animes: Kann zu mehrzeiligen Ausgaben pro Serie führen!" << std::endl << std::endl
              << "    -d, --debug-mode" << std::endl
              << "          Mit dieser Option kann man den Debug-Modus einschalten." << std::endl
              << "          Dabei werden vielmehr Infos ausgegeben." << std::endl << std::endl
              << "    -h, --help" << std::endl
              << "          Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl << std::endl;
}


int unterOption_info(Settings *settings, int argc, char **argv)
{
    settings->modus = Modus::INFO_MODUS;

    int c = 0;
    const option long_opts[] = {
        {"socks5-proxy", required_argument, nullptr, 'p'},
        {"output-file", required_argument, nullptr, 'o'},
        {"internet-pages", required_argument, nullptr, 'i'},
        {"lade-bild-herunter", required_argument, nullptr, 'i'},

        {"use-first-page", no_argument, nullptr, 'f'},
        {"help", no_argument, nullptr, 'h'},
        {"colorless", no_argument, nullptr, 'c'},
        {"debug-mode", no_argument, nullptr, 'd'},
        {"skip-episoden-names", no_argument, nullptr, 'l'},

        {nullptr, no_argument, nullptr, 0}

    };

    while( ( c = getopt_long (argc, argv, "p:o:i:l:fhcds", long_opts, nullptr) ) != -1 ) {
        switch(c) {
            case 'p':
                if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0)
                    return 2;
                break;
            case 'o':
                if(optarg)
                    settings->outputFilePaths.push_back(optarg);
                if(settings->debugMode)
                    std::cout << "Pfad zu Output-Datei: " << settings->outputFilePaths.back() << std::endl;
                break;
            case 'i':
                if(!optarg)
                    break;
                if(setUpInternetPages(*settings, optarg) != 0)
                    return 4356;
                break;
            case 'f':
                settings->useFirstPage = true;
                if(settings->debugMode)
                    std::cout << "useFirstPage: " << settings->useFirstPage << std::endl;
                break;
            case 'h':
                unterOption_info_help(settings->programName);
                return -1;
            case 'c':
                settings->colorless = true;
                if(settings->debugMode)
                    std::cout << "Farblos: true" << std::endl;
                break;
            case 'd':
                settings->debugMode = true;
                if(settings->debugMode)
                    std::cout << "Debug Modus: true" << std::endl;
                break;
            case 'l':
                if(!optarg)
                    break;
                settings->downloadCoverPfad = optarg;
                if(settings->debugMode)
                    std::cout << "downloadCoverPfad: "  << optarg << std::endl;
                break;
            case 's':
                settings->skipEpisodenNameOutput = true;
                if(settings->debugMode)
                    std::cout << "skipEpisodenNameOutput: true" << std::endl;
                break;
            default:
                std::cout << "Aufruf: " << settings->programName << " info [OPTION]... [NAME]..." << std::endl;
                std::cout << "\"" << settings->programName << " info --help\" liefert weitere Informationen." << std::endl;
                return 21;
        }
    }

    //Alle nicht verwendeten Parameter == Name
    while (optind < argc) {
        if(argv[optind][0]) {
            settings->name.append(argv[optind++]).append(" ");
        } else
            ++optind;
    }
    if(settings->name.length() > 0)
        settings->name.pop_back();
    if(settings->debugMode) {
        std::cout << "Name: " << settings->name << std::endl;
        std::cout << "Modus: IndosModus" << std::endl;
    }

    return 0;
}

void unterOption_info_help(std::string programName)
{
    std::cout << "Aufruf: " << programName << " info [OPTION]... [NAME]" << std::endl << std::endl;

    std::cout << "Beschreibung:" << std::endl
              << "    Mit dieser Unterfunktion kann man Informationen zu einer Serie bekommen." << std::endl << std::endl;

    std::cout << "INTERNETSEITEN OPTIONEN:" << std::endl
                  << "    -i [Url1,Url2], --internet-pages [Url1,Url2]" << std::endl
                  << "          Mit dieser Option kann man die Seiten angeben, auf denen" << std::endl
                  << "          nach Serien gesucht werden soll. (Nur Seiten aus Default Wert möglich)" << std::endl
                  << "          Die Seiten Kommagetrennt nach Priorität angeben. (Höchste am Anfang)" << std::endl
                  << "          Gut Kombinierbar mit --use-first-page kombenierbar!" << std::endl
                  << "          Standart: AniWorld.to,serienstream.to" << std::endl
                  << "    -f, --use-first-page" << std::endl
                  << "          Mit dieser Option kann man festlegen, dass direkt die erste Seite," << std::endl
                  << "          auf der die Serie vorhanden ist, verwendet wird. ( Reihenfolge der" << std::endl
                  << "          Priorität nach; siehe -i, --internet-pages)" << std::endl
                  << "          Ohne diesem Parameter ist eine manuelle auswahl nötig," << std::endl
                  << "          wenn diese Serie auf mehreren Seiten existiert!"  << std::endl
                  << "          Parameter kann auch im Default File als standart festgelegt werden!" << std::endl
                  << "          Standart: Überprüfe alle Seiten"  << std::endl << std::endl;

    std::cout << "OPTIONEN:" << std::endl
              << "    -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl
              << "          Mit dieser Option kann man den Socks5Proxy ändern." << std::endl
              << "          Port 0 um Proxy zu deaktivieren." << std::endl
              << "          Standart: 127.0.0.1:9050" << std::endl << std::endl
              << "    -c, --colorless" << std::endl
              << "          Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl
              << "    -d, --debug-mode" << std::endl
              << "          Mit dieser Option kann man den Debug-Modus einschalten." << std::endl
              << "          Dabei werden vielmehr Infos ausgegeben." << std::endl << std::endl
              << "    -s, --skip-episoden-names" << std::endl
              << "          Mit dieser Option kann man die Ausgabe der Namen der" << std::endl
              << "          einzelnen Folgen ausschalten." << std::endl << std::endl
              << "    -o [Pfad], --output-file [Pfad]" << std::endl
              << "          Mit diere Option kann man eine (nichtvorhandene) Text-Datei" << std::endl
              << "          angeben, inwelche die Infos geschrieben werden." << std::endl
              << "    -l [Pfad], --lade-bild-herunter [Pfad]" << std::endl
              << "          Mit diere Option kann man einen Pfad zu einer Datei" << std::endl
              << "          angeben, inwelche das Cover herunter geladen wird." << std::endl
              << "    -h, --help" << std::endl
              << "          Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl;
}


void unterOption_clean(Settings * settings, int argc, char **argv)
{
    if(argc > 2)
        if(strncmp("--help", argv[2], strlen(argv[2])) == 0) {
            std::cout << "Aufruf: " << settings->programName << " clean\n        " << settings->programName << " clean --help" << std::endl << std::endl
                      << "Beschreibung:" << std::endl << "    Mit dieser Unterfunktion kann man die Cookie-Dateien löschen." << std::endl << std::endl;
            return;
        }

    //Um altes zeug zu löschen
    unsigned count = 0;
    if(fileExists(settings->cookieFilePath)) {
        if(remove(settings->cookieFilePath.c_str()) != 0) {
            perror(( " => Error: Das löschen von " + settings->cookieFilePath + " ist fehlgeschlagen: ").c_str());
            return;
        } else
            ++count;
    }

    for (unsigned i = 0; i < UINT_MAX && fileExists(settings->cookieFilePath + std::to_string(i)); ++i) {
        if(remove( (settings->cookieFilePath + std::to_string(i)).c_str() ) != 0) {
            perror((" => Error: Das löschen von " + settings->cookieFilePath  + std::to_string(i) + " ist fehlgeschlagen: ").c_str());
            return;
        } else {
            ++count;
        }
    }
    //UM sachen nach multipage update zu löschen
    for ( const auto &p : settings->pagesALL ) {
        if(fileExists(settings->cookieFilePath + "_" +  p.url)) {
            if(remove((settings->cookieFilePath + "_" +  p.url).c_str()) != 0) {
                perror(( " => Error: Das löschen von " + settings->cookieFilePath + "_" +  p.url + " ist fehlgeschlagen: ").c_str());
                return;
            } else
                ++count;
        }

        for (unsigned i = 0; i < UINT_MAX && fileExists(settings->cookieFilePath + "_" +  p.url + std::to_string(i)); ++i) {
            if(remove( (settings->cookieFilePath + "_" +  p.url + std::to_string(i)).c_str() ) != 0) {
                perror((" => Error: Das löschen von " + settings->cookieFilePath + "_" +  p.url  + std::to_string(i) + " ist fehlgeschlagen: ").c_str());
                return;
            } else {
                ++count;
            }
        }
    }



    if(count == 0)
        std::cout << " => Nichts zu tun: Keine Cookies vorhanden." << std::endl;
    else
        std::cout << " => " << count << " Cookie-File(s) gelöscht." << std::endl;

    return;
}


std::vector<std::string> compare(std::string All_Options_with_komma_between, std::string input)
{
    std::istringstream iStrStream( All_Options_with_komma_between + "\n");
    std::vector<std::string> allFounds;
    std::string line;

    while (getline(iStrStream, line).good())
        if(strncmp(line.c_str(), input.c_str(), input.length()) == 0)
            allFounds.push_back(line);
    return allFounds;
}

bool dirExists(std::string dir)
{
    struct stat sb;
    return (stat(dir.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) ? true : false;
}

bool fileExists (const std::string& name) {
  struct stat buffer;
  return (stat (name.c_str(), &buffer) == 0 && S_ISREG(buffer.st_mode));
}

bool nothingExists(std::string path)
{
    struct stat buffer;
    return (stat(path.c_str(), &buffer) == 0) ? false : true;
}

bool isNumber(std::string number)
{
    bool hasRemovedZero = false;
    for (size_t i = 0; i < number.length(); ++i)
        if( number[i] == '0') {
            number.erase(i, 1);
            i--;
            hasRemovedZero=true;
        }
    if(hasRemovedZero && number == "")
        number="0";

    return (std::to_string(atoll(number.c_str())) == number) ? true : false;
}



int setS5ProxytoSettings(Settings &settings, std::string Optarg)
{
    std::string optarg = Optarg;
    //Ersetze localhost mit 127.0.0.1
    if(optarg.find("localhost") != std::string::npos)
        optarg.insert(optarg.find("localhost"), "127.0.0.1").erase(optarg.find("localhost"), 9);

    //Wenn optarg keine vollständige Addresse ( ip:port ) ist: ip || port
    if(optarg.find(":") == std::string::npos) {
        //Wenn optarg eine Zahl ist, also Port:
        if(isNumber(optarg)) {
            settings.proxy_port = atoi(optarg.c_str());
        //Wenn es scheint eine Ip zu sein, also mit '.':
        } else if (optarg.find(".") != std::string::npos) {
            settings.proxy_ip = optarg;
        // Sonst error:
        } else {
            std::cout << " => Error: Ungültige Socks5 Proxy Addresse: '" << Optarg << "'." << std::endl;
            return 1;
        }
    // Wenn vollständige Addr:
    } else {
        //setze schein Ip:
        settings.proxy_ip = optarg.substr(0, optarg.find(":"));
        //setze Port, falls dieser eine Zahl ist:
        std::string tmpPort = optarg.substr(optarg.find(":") + 1, optarg.length() - optarg.find(":"));
        if(isNumber(tmpPort))
            settings.proxy_port = atoi(optarg.substr(optarg.find(":") + 1, optarg.length() - optarg.find(":")).c_str());
        else {
            std::cout << " => Error: Ungültiger Socks5 Proxy Port: '" << tmpPort << "'."<< std::endl;
            return 2;
        }
    }
    //Überprüfe ob Ip aus 3 * '.' besteht und dann eine  Zahl ist:
    std::string tmpIp = settings.proxy_ip;
    for (int i = 0; i < 3; ++i) {
        if(tmpIp.find(".") != std::string::npos) {
            tmpIp.erase(static_cast<size_t>(tmpIp.find(".")), 1);
        }
        else {
            std::cout << " => Error: Ungültige Socks5 Proxy Ip Addresse: '" << settings.proxy_ip << "'." << std::endl;
            return 3;
        }
    }

    if(!isNumber(tmpIp)) {
        std::cout << " => Error: Ungültige Socks5 Proxy Ip Addresse: '" << settings.proxy_ip << "'." << std::endl;
        return 4;
    // Überprüfe ob Port Positiv oder 0 und kliner als 2 Byte ist:
    } else if (settings.proxy_port < 0 || settings.proxy_port > 65535) {
        std::cout << " => Error: Ungültiger Socks5 Proxy Port ( 0 bis 65535): " << settings.proxy_port << std::endl;
        return 5;
    //Debug Nachricht:
    } else if(settings.debugMode)
        std::cout << "  > Defaults: Proxy Addresse: "<< settings.proxy_ip << ":" << settings.proxy_port << std::endl;

    return 0;

}

bool makePathIsOk(std::string path)
{
    if(path == "") {
        std::cout << " => Error: Üngültiger Pfad: ''." << std::endl;
        return false;
    } else if (path[path.length()-1] == '/' || path[path.length()-1] == '\\')
        path.pop_back();

    if(createDirIsOk(path))
        return true;

    else if(errno == ENOENT) {
        size_t pos = path.find_last_of("/\\");
        if (pos == static_cast<size_t>(std::string::npos))
            return false;
        else if (!makePathIsOk( path.substr(0, pos) ))
            return false;

        // now, try to create again
        return createDirIsOk(path);
    } else if (errno == EEXIST) {
        return dirExists(path);

    } else {
        perror((" => Error: Erstellen von '" + path +"' ist fehlgeschlagen").c_str());
        return false;
    }
}

bool createDirIsOk(std::string path)
{
#ifdef __linux__
    if(mkdir(path.c_str(), 0777) != 0) {
#endif
#ifdef _WIN32
    if(mkdir(path.c_str()) != 0) {
#endif
        //perror((" => Error: Erstellen von dem Ordner '" + path + "' ist fehlgeschlagen").c_str());
        return false;
    } else
        return dirExists(path);
}

int unterOption_news(Settings *settings, int argc, char **argv)
{
    settings->modus = Modus::NEWS_MODUS;

    int c = 0;
    const option long_opts[] = {
        {"socks5-proxy", required_argument, nullptr, 'p'},
        {"use-first-page", no_argument, nullptr, 'f'},

        {"internet-pages", required_argument, nullptr, 'i'},
        {"help", no_argument, nullptr, 'h'},
        {"colorless", no_argument, nullptr, 'c'},
        {"debug-mode", no_argument, nullptr, 'd'},

        {nullptr, no_argument, nullptr, 0}

    };

    while( ( c = getopt_long (argc, argv, "p:i:fhcd", long_opts, nullptr) ) != -1 ) {
        switch(c) {
            case 'p':
                if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0)
                    return 2;
                break;
            case 'i':
                if(!optarg)
                    break;
                if(setUpInternetPages(*settings, optarg) != 0)
                    return 4356;
                break;
            case 'f':
                settings->useFirstPage = true;
                if(settings->debugMode)
                    std::cout << "useFirstPage: " << settings->useFirstPage << std::endl;
                break;
            case 'h':
                unterOption_news_help(settings->programName);
                return -1;
            case 'c':
                settings->colorless = true;
                if(settings->debugMode)
                    std::cout << "Farblos: true" << std::endl;
                break;
            case 'd':
                settings->debugMode = true;
                if(settings->debugMode)
                    std::cout << "Debug Modus: true" << std::endl;
                break;
            default:
                std::cout << "Aufruf: " << settings->programName << " news [OPTION]..." << std::endl;
                std::cout << "\"" << settings->programName << " news --help\" liefert weitere Informationen." << std::endl;
                return 21;
        }
    }

    if(settings->debugMode)
        std::cout << "Modus: NewsModus" << std::endl;

    return 0;
}


void unterOption_news_help(std::string programName)
{
    std::cout << "Aufruf: " << programName << " news [OPTION]..." << std::endl << std::endl;

    std::cout << "Beschreibung:" << std::endl
              << "    Mit dieser Unterfunktion kann man die neuesten 75 Folgen auf serienstream.sx sehen." << std::endl << std::endl;

    std::cout << "INTERNETSEITEN OPTIONEN:" << std::endl
                  << "    -i [Url1,Url2], --internet-pages [Url1,Url2]" << std::endl
                  << "          Mit dieser Option kann man die Seiten angeben, auf denen" << std::endl
                  << "          nach Serien gesucht werden soll. (Nur Seiten aus Default Wert möglich)" << std::endl
                  << "          Die Seiten Kommagetrennt nach Priorität angeben. (Höchste am Anfang)" << std::endl
                  << "          Gut Kombinierbar mit --use-first-page kombenierbar!" << std::endl
                  << "          Standart: AniWorld.to,serienstream.to" << std::endl
                  << "    -f, --use-first-page" << std::endl
                  << "          Mit dieser Option kann man festlegen, dass direkt die erste Seite," << std::endl
                  << "          auf der die Serie vorhanden ist, verwendet wird. ( Reihenfolge der" << std::endl
                  << "          Priorität nach; siehe -i, --internet-pages)" << std::endl
                  << "          Ohne diesem Parameter ist eine manuelle auswahl nötig," << std::endl
                  << "          wenn diese Serie auf mehreren Seiten existiert!"  << std::endl
                  << "          Parameter kann auch im Default File als standart festgelegt werden!" << std::endl
                  << "          Standart: Überprüfe alle Seiten"  << std::endl << std::endl;
    std::cout << "OPTIONEN:" << std::endl
              << "    -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl
              << "          Mit dieser Option kann man den Socks5Proxy ändern." << std::endl
              << "          Port 0 um Proxy zu deaktivieren." << std::endl
              << "          Standart: 127.0.0.1:9050" << std::endl << std::endl
              << "    -c, --colorless" << std::endl
              << "          Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl
              << "    -d, --debug-mode" << std::endl
              << "          Mit dieser Option kann man den Debug-Modus einschalten." << std::endl
              << "          Dabei werden vielmehr Infos ausgegeben." << std::endl << std::endl
              << "    -h, --help" << std::endl
              << "          Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl;
}

int unterOption_update(Settings *settings, int argc, char **argv)
{
    settings->modus = Modus::UPDATE_MODUS;

    //deaktiviere Proxy als Standert
    settings->proxy_port = 0;

    int c = 0;
    const option long_opts[] = {
        {"socks5-proxy", required_argument, nullptr, 'p'},
        {"colorless", no_argument, nullptr, 'c'},

        {"help", no_argument, nullptr, 'h'},
        {"debug-mode", no_argument, nullptr, 'd'},

        {nullptr, no_argument, nullptr, 0}

    };

    while( ( c = getopt_long (argc, argv, "p:chd", long_opts, nullptr) ) != -1 ) {
        switch(c) {
            case 'p':
                if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0)
                    return 2;
                break;
            case 'c':
                settings->colorless = true;
                if(settings->debugMode)
                    std::cout << "Farblos: true" << std::endl;
                break;
            case 'h':
                unterOption_update_help(settings->programName);
                return -1;
            case 'd':
                settings->debugMode = true;
                if(settings->debugMode)
                    std::cout << "Debug Modus: true" << std::endl;
                break;
            default:
                std::cout << "Aufruf: " << settings->programName << " --update [OPTION]..." << std::endl;
                std::cout << "\"" << settings->programName << " --update --help\" liefert weitere Informationen." << std::endl;
                return 21;
        }
    }

    if(settings->debugMode)
        std::cout << "Modus: UpdateModus" << std::endl;

    return 0;
}

void unterOption_update_help(std::string programName)
{
    std::cout << "Aufruf: " << programName << " --update [OPTION]..." << std::endl << std::endl;

    std::cout << "Beschreibung:" << std::endl
              << "    Mit dieser Unterfunktion kann man das Programm updaten." << std::endl << std::endl;

    std::cout << "OPTIONEN:" << std::endl
              << "    -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl
              << "          Mit dieser Option kann man den Socks5Proxy ändern." << std::endl
              << "          Port 0 um Proxy zu deaktivieren." << std::endl
              << "          Standart: Deaktiviert -> Port 0" << std::endl << std::endl
              << "    -c, --colorless" << std::endl
              << "          Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl
              << "    -d, --debug-mode" << std::endl
              << "          Mit dieser Option kann man den Debug-Modus einschalten." << std::endl
              << "          Dabei werden vielmehr Infos ausgegeben." << std::endl << std::endl
              << "    -h, --help" << std::endl
              << "          Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl;
}


bool removeDirIsOk(std::string path, Settings *settings, bool askForDelete)
{
    if(path == "") {
        std::cout << " => Error: Ungültiger Pfad: '" << path << "'." << std::endl;
        return false;
    } else if(path.back() != settings->pathSymbol )
        path.push_back(settings->pathSymbol);

    if(askForDelete) {
        std::cout << "Zur Bestätigung des Löschens des Ordners: '" << path << "'," << std::endl
                  << "geben sie 'OK' ein: " << std::flush;
        std::string input;
        std::cin.clear();
        std::getline(std::cin, input);
        if(input != "OK") {
            std::cout << "Abbruch..." << std::endl;
            return true;
        }

    }

    DIR* dirp = nullptr;
    if( (dirp = opendir( path.c_str() )) == nullptr ) {
        perror(std::string(" => Error: Konnte Verzeichnis nicht aufmachen: '" + path + "'").c_str());
        return false;
    }

    struct dirent * dp;
    while ((dp = readdir(dirp)) != nullptr) {
        if(strcmp( dp->d_name, "." ) == 0 || strcmp ( dp->d_name, ".." ) == 0)
            continue;
        else if(dirExists((path + dp->d_name + settings->pathSymbol ))) { //if(dp->d_type == DT_DIR) {
            if( ! removeDirIsOk(path + dp->d_name + settings->pathSymbol , settings, false/*askForDelete*/)) {
                if(settings->debugMode)
                    std::cout << " => Error im Unterordner: '" << path + dp->d_name << "'" << std::endl;
                return false;
            }
        } else if(fileExists( path + dp->d_name )) {
            if(remove((path + dp->d_name).c_str()) != 0) {
                perror((" => Error: Das Löschen von '" + path + dp->d_name + "' ist fehlgeschlagen").c_str());
                return false;
            } else {
                if(settings->debugMode)
                    std::cout << " => DEBUG: Erfolgreich '" << path + dp->d_name << "' gelöscht." << std::endl;
            }
        } else {
            std::cout << " => Error: '" << path << dp->d_name << "'ist keine Datei oder Ordner." << std::endl;
            return false;
        }

    }
    closedir(dirp);

    if(rmdir(path.c_str()) != 0) {
        perror((" => Das löschen des Ordners '" + path + "' ist fehlgeschlagen.").c_str());
        return false;

    } else if (settings->debugMode)
        std::cout << " => DEBUG: Ordner '" << path << "' erfolgreich gelöscht." << std::endl;

    return true;
}

int unterOption_RemoveSettings_or_CacheDir(Settings *settings, int argc, char **argv)
{
    settings->modus = Modus::REMOVE_SETTINGS_AND_CACHE_MODUS;

    int c = 0;
    const option long_opts[] = {
        {"help", no_argument, nullptr, 'h'},
        {"debug-mode", no_argument, nullptr, 'd'},
        {nullptr, no_argument, nullptr, 0}

    };

    while( ( c = getopt_long (argc, argv, "hd", long_opts, nullptr) ) != -1 ) {
        switch(c) {

            case 'h':
                unterOption_RemoveSettings_or_CacheDire_help(settings->programName);
                return -1;
            case 'd':
                settings->debugMode = true;
                if(settings->debugMode)
                    std::cout << "Debug Modus: true" << std::endl;
                break;
            default:
                std::cout << "Aufruf: " << settings->programName << " --remove [OPTION]... [settings|cache|all]" << std::endl;
                std::cout << "\"" << settings->programName << " --remove --help\" liefert weitere Informationen." << std::endl;
                return 21;
        }
    }

    //Alle nicht verwendeten Parameter == Name
    while (optind < argc) {
        if(argv[optind][0]) {
            settings->name.append(argv[optind++]).append(" ");
        } else
            ++optind;
    }
    if(settings->name.length() > 0)
        settings->name.pop_back();
    else {
        std::cout << " => Error: Keinen Ordner angegeben." << std::endl;
        std::cout << "Aufruf: " << settings->programName << " --remove [OPTION]... [settings|cache|all]" << std::endl;
        std::cout << "\"" << settings->programName << " --remove --help\" liefert weitere Informationen." << std::endl;
        return 22;
    }



    if(settings->debugMode)
        std::cout << "Modus: RemoveModus" << std::endl;

    return 0;
}


void unterOption_RemoveSettings_or_CacheDire_help(std::string programName)
{
    std::cout << "Aufruf: " << programName << " --remove [OPTION]... [settings|cache|all]" << std::endl << std::endl;

    std::cout << "Beschreibung:" << std::endl
              << "    Mit dieser Unterfunktion kann man die erstellten Settings/Cache" << std::endl
              << "    Ordner löschen." << std::endl
              << "    'settings': Nur den Ordner mit den Einstellungen löschen." << std::endl
              << "    'cache': Nur den Ordner mit den Zwischengespeicherten Dateien löschen." << std::endl
              << "    'all': Beide Ordner löschen." << std::endl << std::endl;

    std::cout << "OPTIONEN:" << std::endl
              << "    -d, --debug-mode" << std::endl
              << "          Mit dieser Option kann man den Debug-Modus einschalten." << std::endl
              << "          Dabei werden vielmehr Infos ausgegeben." << std::endl << std::endl
              << "    -h, --help" << std::endl
              << "          Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl;
}

bool isSame(char **argv, std::string FunktionName)
{
    if(strncmp(argv[1], FunktionName.c_str(), strlen(argv[1])) == 0) {
        argv[1][0] = '\0';
        return true;
    }
    return false;
}

int unterOption_printLogFile(Settings *settings, int argc, char **argv)
{
    settings->modus = Modus::PRINT_LOG_FILE_MODUS;

    int c = 0;
    const option long_opts[] = {
        {"help", no_argument, nullptr, 'h'},
        {"print", no_argument, nullptr, 'p'},
        {"clear", no_argument, nullptr, 'C'},
        {"colorless", no_argument, nullptr, 'c'},
        {nullptr, no_argument, nullptr, 0}

    };

    bool printMode = false, ClearMode = false;

    while( ( c = getopt_long (argc, argv, "hpCc", long_opts, nullptr) ) != -1 ) {
        switch(c) {

            case 'h':
                unterOption_printLogFile(settings->programName);
                return -1;
            case 'p':
                printMode = true;
                if(settings->debugMode)
                    std::cout << "printMode: true" << std::endl;
                break;
            case 'C':
                ClearMode = true;
                if(settings->debugMode)
                    std::cout << "ClearMode: true" << std::endl;
                break;
            case 'c':
                settings->colorless = true;
                if(settings->debugMode)
                    std::cout << "Farblos: true" << std::endl;
                break;
            default:
                std::cout << "Aufruf: " << settings->programName << " log [OPTION]..." << std::endl;
                std::cout << "\"" << settings->programName << " log --help\" liefert weitere Informationen." << std::endl;
                return 21;
        }
    }

    if(!printMode && !ClearMode) {
        std::cout << " => Error: Fehlende Parameter: -p, --print oder -C, --clear." << std::endl;
        std::cout << "\"" << settings->programName << " log --help\" liefert weitere Informationen." << std::endl;
        return 34;
    }

    // Main-Program:......

    std::string clearColor = "\033[0m";

    if(printMode && settings->colorless)
        std::cout << Logger(settings->logFilePath).getLogText() << std::endl;
    else if(printMode) {
        std::string text = settings->logFilePath + ":\n" + Logger(settings->logFilePath).getLogText();
        //Command Lines
        text = replace(text, ": \"", clearColor + ": " +  "\033[94m" + "\"");
        text = replace(text, "\n -> ", std::string("\n -> ")+ "\033[95m" );

        //Good Links
        text = replace(text, ": http", clearColor + ": " + "\033[92m" + "http");
        text = replace(text, "\nS", std::string("\n" ) + "\033[33m" + "S");

        //Names:
        text = replace(text, "\nName: ", "\n" + std::string("\033[93m") + "Name: " + std::string("\033[96m"));

        //Line/ Text - End
        text = replace(text, "\n",  "\n" + clearColor);
        text.append(clearColor);
        std::cout << text << std::endl;
    }
    if(ClearMode)
        if(Logger(settings->logFilePath).clearFile())
            return 12;
    return -1;
}

void unterOption_printLogFile(std::string programName)
{
    std::cout << "Aufruf: " << programName << " log [OPTION]... [KOMMANDO]" << std::endl
              << "        " << programName << " log [OPTION]... [{-p, --print}/{-C, --clear}]" << std::endl << std::endl;

    std::cout << "Beschreibung:" << std::endl
              << "    Mit dieser Unterfunktion kann man die Log Datei sehen/leeren." << std::endl << std::endl;

    std::cout << "KOMMANDOS:" << std::endl
              << "    -p, --print" << std::endl
              << "          Mit dieser Option wird das LogFile ausgegeben." << std::endl
              << "    -C, --clear" << std::endl
              << "          Mit dieser Option wird das LogFile geleert." << std::endl;

    std::cout << "OPTION(EN):" << std::endl
              << "    -c, --colorless" << std::endl
              << "          Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl;
}

std::string replace(std::string str, std::string substr1, std::string substr2)
{
    if(substr1 == "")
        return str;
    size_t index = 0;
    for (index = str.find(substr1, index); index != std::string::npos; index = str.find(substr1, index + substr2.length() ) )
        str.replace(index, substr1.length(), substr2);
    return str;
}

int setUpInternetPages(Settings &settings, std::string optarg)
{
    //Lösche default
    settings.pagesInUse.clear();

    std::istringstream ss(optarg + ",");
    std::string value;

    while(std::getline(ss, value, ',')) {
        if(value == "")
            continue;
        value = PageManager::upper_string(value);
        if(value == "ALL") {
            for( const auto & internetSeite : settings.pagesALL )
                settings.pagesInUse.push_back(internetSeite);
            break;
        }
        bool found = false;
        for( const auto & internetSeite : settings.pagesALL ) {
            if( value == PageManager::upper_string( internetSeite.url ) ) {
                settings.pagesInUse.push_back( internetSeite );
                if(settings.debugMode)
                    std::cout << "  > : Internetseiten pusback: " << internetSeite.url << std::endl;
                found = true;
            }
        }
        if( !found ) {
            std::cout << " => Error: Unbekannte Internetseiten: " << value << " - Bitte überprüfen sie ihr Default File oder ggf. Parameter -i" << std::endl;
            return 2154;
        }
    }
    if(settings.pagesInUse.size() < 1) {
        std::cout << " => Keine Internetseiten angegeben! " << std::endl;
        return 1236;
    }
    return 0;
}

int unterOption_printJD2_renameSkript(Settings *settings, int , char **)
{
    std::cout << "// Settings" << std::endl
        << "var FilePath = \"" << settings->logFilePath << "\";" << std::endl
        << "var ReplaceWholeName = false;" << std::endl
        << "var Delimeter = \"_\"; // S01E01 + Delimeter + Oldname.mp4" << std::endl
        << "" << std::endl
        << "//Global Vars" << std::endl
        << "var LinkFile = readFile(FilePath); // *Read a text file" << std::endl
        << "var LinkFileLineArray = LinkFile.split('\n');" << std::endl
        << "var myDownloadLink = getAllDownloadLinks(); // *Get a list of all downloadlinks" << std::endl
        << "" << std::endl
        << "" << std::endl
        << "for (var i = 0; i < myDownloadLink.length; i++) {" << std::endl
        << "" << std::endl
        << "    var url = myDownloadLink[i].getUrl();" << std::endl
        << "    var EpisodeName = myDownloadLink[i].getName();" << std::endl
        << "    var foundLine = true;" << std::endl
        << "    var LineWithEp = "";" << std::endl
        << "" << std::endl
        << "    if (EpisodeName.indexOf(\".mp4\") == -1) continue;" << std::endl
        << "" << std::endl
        << "    for (var x = LinkFileLineArray.length - 1; x >= 0; x--)" << std::endl
        << "       if (LinkFileLineArray[x].indexOf(url) !== -1) {" << std::endl
        << "            LineWithEp = LinkFileLineArray[x];" << std::endl
        << "            break;" << std::endl
        << "        } else if (x == 0) {" << std::endl
        << "        //alert(\"Error: Für den Link '\" + url + \"' wurde in dem TextFile: '\" + FilePath + \"' keine Passende Zeile gefunden.\");" << std::endl
        << "       foundLine = false;" << std::endl
        << "    }" << std::endl
        << "    if (!foundLine) continue;" << std::endl
        << "" << std::endl
        << "    var addPart = LineWithEp.substring(0, LineWithEp.indexOf(\":\"));" << std::endl
        << "    if (EpisodeName.indexOf(addPart) !== -1) continue;" << std::endl
        << "    if (ReplaceWholeName) myDownloadLink[i].setName(addPart + EpisodeName.substring(EpisodeName.lastIndexOf(\".\")));" << std::endl
        << "    else myDownloadLink[i].setName(addPart + Delimeter + EpisodeName)" << std::endl
        << "" << std::endl
        << "}" << std::endl;
    return 0;
}