#!/usr/bin/env python
#
# This file is part of pacman-mirrors.
#
# pacman-mirrors is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pacman-mirrors is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pacman-mirrors.  If not, see <http://www.gnu.org/licenses/>.
#
# Authors: Frede Hundewadt <echo ZmhAbWFuamFyby5vcmcK | base64 -d>

"""Pacman-Mirrors Configuration Functions"""

import sys
from typing import Dict, Any, Tuple, List

from pacman_mirrors.config import configuration as conf
from pacman_mirrors.constants import txt
from pacman_mirrors.functions import util


def setup_config(self) -> tuple:
    """Get config information
    :returns: config, custom
    :rtype: tuple
    """
    custom = False
    # default config
    config: dict[str | Any, str | tuple[str, str, str] | list[Any] | bool | Any] = {
        "arm": False,
        "branch": "stable",
        "branches": conf.BRANCHES,
        "config_file": conf.CONFIG_FILE,
        "country_pool": [],
        "custom_file": conf.CUSTOM_FILE,
        "enterprise": False,
        "method": "rank",
        "mirror_file": conf.MIRROR_FILE,
        "mirror_list": conf.MIRROR_LIST,
        "no_update": False,
        "protocols": [],
        "repo_arch": conf.REPO_ARCH,
        "ssl_verify": True,
        "static": "",
        "statistic": False,
        "status_file": conf.STATUS_FILE,
        "test_file": conf.TEST_FILE,
        "timeout": 2,
        "url_mirrors_json": conf.URL_MIRROR_JSON,
        "url_status_json": conf.URL_STATUS_JSON,
        "work_dir": conf.WORK_DIR,
    }
    # try to replace default entries by reading conf file
    try:
        with open(config["config_file"]) as conf_file:
            for line in conf_file:
                line = line.strip()
                if line.startswith("#") or "=" not in line:
                    continue

                (key, value) = line.split("=", 1)
                key = key.rstrip()
                value = value.lstrip()
                if key and value:
                    if value.startswith('"') and value.endswith('"'):
                        value = value[1:-1]

                    if key == "Method":
                        config["method"] = value

                    if key == "Branch":
                        config["branch"] = value

                    if key == "Protocols":
                        if "," in value:
                            config["protocols"] = value.split(",")
                        else:
                            config["protocols"] = value.split(" ")

                    if key == "SSLVerify":
                        config["ssl_verify"] = value.lower().capitalize()

                    if key == "TestFile":
                        config["test_file"] = value
                        if not config["test_file"]:
                            config["test_file"] = conf.TEST_FILE

                    if key == "Static":
                        config["enterprise"] = True
                        config["static"] = value

                    if key == "Statistic":
                        config["statistic"] = True

    except (PermissionError, OSError) as err:
        util.msg(
            message=f"{txt.CANNOT_READ_FILE}: {err.filename}: {err.strerror}",
            urgency=txt.ERR_CLR,
            tty=self.tty,
        )

        sys.exit(2)

    return config, custom


def sanitize_config(config: dict) -> bool:
    """
    Verify configuration
    :param config:
    """
    errors = []
    if config["method"] not in conf.METHODS:
        errors.append(
            f"     'Method = {config['method']}'; {txt.EXP_CLR} {'|'.join(conf.METHODS)}"
        )

    if config["arm"]:
        if config["branch"] not in conf.ARM_BRANCHES:
            errors.append(
                "     'Branch = {}'; {} {}".format(
                    config["branch"], txt.EXP_CLR, "|".join(conf.ARM_BRANCHES)
                )
            )
    else:
        if config["branch"] not in conf.BRANCHES:
            errors.append(
                "     'Branch = {}'; {} {}".format(
                    config["branch"], txt.EXP_CLR, "|".join(conf.BRANCHES)
                )
            )

    if str(config["ssl_verify"]) not in conf.SSL:
        errors.append(
            "     'SSLVerify = {}'; {} {}".format(
                config["ssl_verify"], txt.EXP_CLR, "|".join(conf.SSL)
            )
        )

    for p in config["protocols"]:
        if p not in conf.PROTOCOLS:
            errors.append(
                "     'Protocols = {}'; {} {}".format(
                    config["protocols"], txt.EXP_CLR, ",".join(conf.PROTOCOLS)
                )
            )

    if config["enterprise"]:
        # check static mirror - simple validation
        if "://" or "." not in config["static"]:
            errors.append(
                "     'Static = {}'; {} (e.g. 'https://mirror1.tld/manjaro/')".format(
                    config["static"], txt.EXP_CLR
                )
            )

    if len(errors) != 0:
        print(f".: {txt.ERR_CLR}: {txt.INVALID_SETTING_IN} `{conf.CONFIG_FILE}`")
        for e in errors:
            print(e)
        return False
    return True
