"""
Set license for a Project

Can either select the license with the --license flag,
or a selectable list will be provided.
"""

import argparse
import dataclasses
import re
from datetime import date
from pathlib import Path
from subprocess import check_output

import requests
from pzp import pzp
from tomlkit import dump, load

WELL_KNOWN_LICENSE = ["mit", "gpl"]


@dataclasses.dataclass
class License:
    key: str
    name: str
    spdx_id: str
    url: str
    node_id: str

    def __str__(self):
        return self.name

    def text(self) -> str:
        result = requests.get(self.url)
        result.raise_for_status()
        return result.json()["body"]


def get_user() -> str:
    return check_output(["git", "config", "user.name"], encoding="utf8").strip()


def get_licenses() -> dict:
    result = requests.get("https://api.github.com/licenses")
    result.raise_for_status()
    return {data["key"]: License(**data) for data in result.json()}


def main() -> None:
    choices = get_licenses()

    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        "--pyproject",
        nargs="?",
        type=Path,
        default="pyproject.toml",
        help="Path to pyproject %(default)s",
    )
    parser.add_argument("--license", choices=choices.keys())
    args = parser.parse_args()

    if args.license is None:
        license: License = pzp(
            choices.values(),
            fullscreen=False,
        )
    else:
        license: License = choices[args.license]

    # Update pyproject with the spdx compatible line
    with args.pyproject.open("rb") as fp:
        pyproject = load(fp)
    pyproject["project"]["license"] = license.spdx_id
    with args.pyproject.open("w") as fp:
        dump(pyproject, fp)

    # And then write the license file to our project directory

    replacements = {
        "[fullname]": get_user(),
        "[year]": str(date.today().year),
    }

    sorted_keys = sorted(replacements.keys(), key=len, reverse=True)
    pattern = re.compile("|".join(re.escape(key) for key in sorted_keys))
    modified_text = pattern.sub(lambda match: replacements[match.group(0)], license.text())

    with open("LICENSE", "w") as fp:
        fp.write(modified_text)
