/*
 * This file is part of smolbote. It's copyrighted by the contributors recorded
 * in the version control history of the file, available from its original
 * location: https://neueland.iserlohn-fortress.net/smolbote.hg
 *
 * SPDX-License-Identifier: GPL-3.0
 */

#include "configuration.h"
#include <QStandardPaths>
#include <fstream>
#include <boost/algorithm/string/predicate.hpp>

namespace po = boost::program_options;

Configuration::Configuration()
{
    m_homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString();

    // create description
    desc.add_options()

        // main window ui
        ("mainwindow.height", po::value<int>()->default_value(720))
        ("mainwindow.width", po::value<int>()->default_value(1280))
        ("mainwindow.maximized", po::value<bool>()->default_value(true))
        ("mainwindow.title", po::value<std::string>()->default_value(" — smolbote"))

        // main window shortcuts
        ("mainwindow.shortcuts.newTab", po::value<std::string>()->default_value("Ctrl+T"))
        ("mainwindow.shortcuts.newGroup", po::value<std::string>()->default_value("Ctrl+G"))
        ("mainwindow.shortcuts.newWindow", po::value<std::string>()->default_value("Ctrl+N"))

        ("mainwindow.shortcuts.about", po::value<std::string>()->default_value("F1"))
        ("mainwindow.shortcuts.quit", po::value<std::string>()->default_value("Ctrl+Q"))

        ("mainwindow.shortcuts.tileWindows", po::value<std::string>()->default_value("F9"))

        // navigation
        ("navigation.movable", po::value<bool>()->default_value(false))
        ("navigation.shortcuts.back", po::value<std::string>()->default_value("Ctrl+Left"))
        ("navigation.shortcuts.forward", po::value<std::string>()->default_value("Ctrl+Right"))
        ("navigation.shortcuts.refresh", po::value<std::string>()->default_value("F5"))
        ("navigation.shortcuts.reload", po::value<std::string>()->default_value("Ctrl+F5"))
        ("navigation.shortcuts.home", po::value<std::string>()->default_value("Ctrl+Home"))

        // address bar
        ("addressbar.shortcuts.focus", po::value<std::string>()->default_value("F4"))
        ("addressbar.shortcuts.pageMenu", po::value<std::string>()->default_value("F2"))
        ("addressbar.shortcuts.toolsMenu", po::value<std::string>()->default_value("F10"))

        // tab bar
        ("tabbar.shortcuts.new", po::value<std::string>()->default_value("Ctrl+T"))
        ("tabbar.shortcuts.close", po::value<std::string>()->default_value("Ctrl+X"))
        ("tabbar.shortcuts.left", po::value<std::string>()->default_value("Ctrl+O"))
        ("tabbar.shortcuts.right", po::value<std::string>()->default_value("Ctrl+P"))

        // page
        ("browser.shortcuts.toggleSearchBox", po::value<std::string>()->default_value("F3"))
        ("browser.shortcuts.fullscreen", po::value<std::string>()->default_value("F11"))

        // Filter settings
        ("filter.path", po::value<std::string>()->default_value("~/.config/smolbote/hosts.d"))
        ("filter.cookies.block.all", po::value<bool>()->default_value(false))
        ("filter.cookies.block.thirdParty", po::value<bool>()->default_value(true))
        ("filter.cookies.path", po::value<std::string>()->default_value("~/.config/smolbote/cookies.d"))

        // Plugin settings
        ("plugins.path", po::value<std::string>()->default_value("~/.config/smolbote/plugins.d"))

        // Profile settings
        // default profile name the browser should use; "" is off-the-record
        ("profile.default", po::value<std::string>()->default_value(""))
        ("profile.path", po::value<std::string>()->default_value("~/.config/smolbote/profiles.d"))
        ("profile.search", po::value<std::string>()->default_value("https://duckduckgo.com/?q=$term&ia=web"))
        ("profile.homepage", po::value<std::string>()->default_value("about:blank"))
        ("profile.newtab", po::value<std::string>()->default_value("about:blank"))

        // Bookmark settings
        ("bookmarks.path", po::value<std::string>()->default_value("~/.config/smolbote/bookmarks.xbel"))
        ("bookmarks.shortcut", po::value<std::string>()->default_value("Ctrl+B"))

        // Downloads settings
        ("downloads.path", po::value<std::string>()->default_value("~/Downloads"))
        ("downloads.shortcut", po::value<std::string>()->default_value("Ctrl+D"))
        ;

    // store the defaults into the vm
    {
        const char *argv[0];
        po::store(po::parse_command_line(0, argv, desc), vm);
    }
}

Configuration::~Configuration() = default;

QString Configuration::defaultUserConfigLocation()
{
    // try to locate an existing config
    QString path = QStandardPaths::locate(QStandardPaths::ConfigLocation, "smolbote/smolbote.cfg");

    // it's possible there is no config, so set the path properly
    if(path.isEmpty())
        path = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/smolbote/smolbote.cfg";

    return path;
}

bool Configuration::read(const QString &path)
{
    std::ifstream f(path.toStdString(), std::ifstream::in);

    // parse_config_file(file, options_description, allow_unregistered)
    po::store(po::parse_config_file(f, desc, true), vm);
    return true;
}

bool Configuration::parse(int argc, const char **argv)
{
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);
    } catch(const po::error &e) {
        return false;
    }

    return true;
}

QHash<QString, QString> Configuration::section(const std::string &prefix) const
{
    QHash<QString, QString> v;
    for(auto &s : desc.options()) {
        if(boost::starts_with(s->long_name(), prefix)) {
            v[s->long_name().c_str()] = QString::fromStdString(value<std::string>(s->long_name().c_str()).value());
        }
    }

    return v;
}