from hatch.template import File, files_default, find_template_files
from hatch.template.plugin.interface import TemplateInterface
from hatch.utils.fs import Path
from hatch.utils.network import download_file


class DefaultTemplate(TemplateInterface):
    PLUGIN_NAME = "default"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.plugin_config.setdefault("ci", False)
        self.plugin_config.setdefault("src-layout", True)
        self.plugin_config.setdefault("tests", True)

    def initialize_config(self, config):
        # Default values
        config["readme_file_path"] = "README.md"
        config["package_metadata_file_path"] = f"src/{config['package_name']}/__about__.py"

        license_data = {}

        # Licenses
        license_ids = config["licenses"]["default"]
        if not license_ids:
            config["license_data"] = license_data
            config["license_expression"] = ""
            config["license_files"] = ""
            config["license_header"] = ""
            return

        cached_licenses_dir = self.cache_dir / "licenses"
        cached_licenses_dir.ensure_dir_exists()

        license_ids = sorted(set(license_ids))
        for license_id in sorted(set(license_ids)):
            license_file_name = f"{license_id}.txt"
            cached_license_path = cached_licenses_dir / license_file_name
            if not cached_license_path.is_file():
                from packaging.licenses._spdx import VERSION  # noqa: PLC2701

                url = f"https://raw.githubusercontent.com/spdx/license-list-data/v{VERSION}/text/{license_file_name}"
                for _ in range(5):
                    try:
                        download_file(cached_license_path, url)
                    except Exception:  # noqa: BLE001, S112
                        continue
                    else:
                        break

            license_data[license_id] = cached_license_path.read_text(encoding="utf-8")

        config["license_data"] = license_data
        config["license_expression"] = " OR ".join(license_data)
        config["license_header"] = (
            ""
            if not config["licenses"]["headers"]
            else f"""\
# SPDX-FileCopyrightText: {self.creation_time.year}-present {config["name"]} <{config["email"]}>
#
# SPDX-License-Identifier: {config["license_expression"]}
"""
        )
        if len(license_ids) == 1:
            config["license_files"] = ""
        else:
            config["license_files"] = '\nlicense-files = { globs = ["LICENSES/*"] }'

        if config["args"]["cli"]:
            config["dependencies"].add("click")

        if not self.plugin_config["src-layout"]:
            config["package_metadata_file_path"] = f"{config['package_metadata_file_path'][4:]}"

    def get_files(self, config):
        files = list(find_template_files(files_default))

        # Add any licenses
        license_data = config["license_data"]
        if license_data:
            if len(license_data) == 1:
                license_id, text = next(iter(license_data.items()))
                license_text = get_license_text(config, license_id, text, self.creation_time)
                files.append(File(Path("LICENSE.txt"), license_text))
            else:
                # https://reuse.software/faq/#multi-licensing
                for license_id, text in license_data.items():
                    license_text = get_license_text(config, license_id, text, self.creation_time)
                    files.append(File(Path("LICENSES", f"{license_id}.txt"), license_text))

        if config["args"]["cli"]:
            from hatch.template import files_feature_cli

            files.extend(find_template_files(files_feature_cli))

        if self.plugin_config["tests"]:
            from hatch.template import files_feature_tests

            files.extend(find_template_files(files_feature_tests))

        if self.plugin_config["ci"]:
            from hatch.template import files_feature_ci

            files.extend(find_template_files(files_feature_ci))

        return files

    def finalize_files(self, config, files):
        if config["licenses"]["headers"] and config["license_data"]:
            for template_file in files:
                if template_file.path.name.endswith(".py"):
                    template_file.contents = config["license_header"] + template_file.contents

        if self.plugin_config["src-layout"]:
            for template_file in files:
                if template_file.path.parts[0] == config["package_name"]:
                    template_file.path = Path("src", template_file.path)


def get_license_text(config, license_id, license_text, creation_time):
    if license_id == "MIT":
        license_text = license_text.replace("<year>", f"{creation_time.year}-present", 1)
        license_text = license_text.replace("<copyright holders>", f"{config['name']} <{config['email']}>", 1)
    elif license_id == "BSD-3-Clause":
        license_text = license_text.replace("<year>", f"{creation_time.year}-present", 1)
        license_text = license_text.replace("<owner>", f"{config['name']} <{config['email']}>", 1)

    return f"{license_text.rstrip()}\n"
