#!/usr/bin/env python3
#
# Copyright 2021 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# pylint: disable=missing-function-docstring
# pylint: disable=too-many-instance-attributes
# pylint: disable=unspecified-encoding
# pylint: disable=invalid-name
"""Tool classes to handle a Bazel registry"""

import base64
import difflib
import functools
import hashlib
import json
import netrc
import pathlib
import posixpath
import re
import shutil
import urllib.parse
import urllib.request
import yaml
from urllib.error import HTTPError

GREEN = "\x1b[32m"
RESET = "\x1b[0m"

PRESUBMIT_YML = "presubmit.yml"
MODULE_DOT_BAZEL = "MODULE.bazel"


def log(msg):
    print(f"{GREEN}INFO: {RESET}{msg}")


def download(url):
    authorization_header_name = "Authorization"

    class Github404ErrorProcessor(urllib.request.BaseHandler):
        """Work around Github authorization header weirdness.

        For private archives, Github requires an authorization token
        in the initial GET, but no token on the redirected request
        (which contains a token in the URL).  An authorization token
        leads to a 404, which we handle here.  By default, urllib
        includes all the original headers in the redirected request.

        """

        def http_error_404(self, request, fp, code, msg, hdrs):
            # Try again without the Authorization header.
            auth = request.headers.pop(authorization_header_name, None)
            if auth is None:
                raise HTTPError(req.full_url, code, msg, headers, fp)
            new = urllib.request.Request(request.full_url, headers=request.headers)
            fp.read()
            fp.close()
            return self.parent.open(new, timeout=request.timeout)

    opener = urllib.request.build_opener(Github404ErrorProcessor)
    urllib.request.install_opener(opener)
    parts = urllib.parse.urlparse(url)
    headers = {"User-Agent": "curl/8.7.1"}  # Set the User-Agent header
    try:
        authenticators = netrc.netrc().authenticators(parts.netloc)
    except FileNotFoundError:
        authenticators = None
    if authenticators != None:
        (login, _, password) = authenticators
        req = urllib.request.Request(url, headers=headers)
        creds = base64.b64encode(str.encode("%s:%s" % (login, password))).decode()
        req.add_header(authorization_header_name, "Basic %s" % creds)
    else:
        req = urllib.request.Request(url, headers=headers)

    with urllib.request.urlopen(req) as response:
        return response.read()


def download_file(url, file):
    with open(file, "wb") as f:
        f.write(download(url))


def read(path):
    with open(path, "rb") as file:
        return file.read()


def integrity(data, algorithm="sha256"):
    assert algorithm in {
        "sha224",
        "sha256",
        "sha384",
        "sha512",
    }, "Unsupported SRI algorithm"
    hash = getattr(hashlib, algorithm)(data)
    encoded = base64.b64encode(hash.digest()).decode()
    return f"{algorithm}-{encoded}"


def integrity_for_comparison(data, expected_integrity):
    algorithm, _ = expected_integrity.split("-", 1)
    return integrity(data, algorithm)


def json_dump(file, data, sort_keys=True):
    with open(file, "w", newline="\n") as f:
        json.dump(data, f, indent=4, sort_keys=sort_keys)
        f.write("\n")


# Translated from:
# https://github.com/bazelbuild/bazel/blob/79a53def2ebbd9358450f739ea37bf70662e8614/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/Version.java#L58
@functools.total_ordering
class Version:
    @functools.total_ordering
    class Identifier:
        def __init__(self, s):
            if not s:
                raise RegistryException("identifier is empty")
            self.val = int(s) if s.isnumeric() else s

        def __eq__(self, other):
            if type(self.val) != type(other.val):
                return False
            return self.val == other.val

        def __lt__(self, other):
            if type(self.val) != type(other.val):
                return type(self.val) == int
            return self.val < other.val

    @staticmethod
    def convert_to_identifiers(s):
        if s == None:
            return None
        return [Version.Identifier(i) for i in s.split(".")]

    def __init__(self, version_str):
        PATTERN = re.compile(r"^([a-zA-Z0-9.]+)(?:-([a-zA-Z0-9.-]+))?(?:\+[a-zA-Z0-9.-]+)?$")
        m = PATTERN.match(version_str)
        if not m:
            raise RegistryException(f"`{version_str}` is not a valid version")
        self.release = Version.convert_to_identifiers(m.groups()[0])
        self.prerelease = Version.convert_to_identifiers(m.groups()[1])

    def __eq__(self, other):
        return (self.release, self.prerelease) == (other.release, other.prerelease)

    def __lt__(self, other):
        if self.release != other.release:
            return self.release < other.release
        if self.prerelease == None:
            return False
        if other.prerelease == None:
            return True
        return self.prerelease < other.prerelease


class Module:
    """A class to represent all information of a Bazel module."""

    def __init__(self, name=None, version=None, compatibility_level=1):
        self.name = name
        self.version = version
        self.compatibility_level = compatibility_level
        self.module_dot_bazel = None
        self.url = None
        self.strip_prefix = None
        self.deps = []
        self.patches = []
        self.patch_strip = 0
        self.build_file = None
        self.presubmit_yml = None
        self.build_targets = []
        self.test_module_path = None
        self.test_module_build_targets = []
        self.test_module_test_targets = []

    def add_dep(self, module_name, version):
        self.deps.append((module_name, version))
        return self

    def set_module_dot_bazel(self, module_dot_bazel):
        self.module_dot_bazel = module_dot_bazel
        return self

    def set_source(self, url, strip_prefix=None):
        self.url = url
        self.strip_prefix = strip_prefix
        return self

    def add_patch(self, patch_file):
        self.patches.append(patch_file)
        return self

    def set_patch_strip(self, patch_strip):
        self.patch_strip = patch_strip
        return self

    def set_build_file(self, build_file):
        self.build_file = build_file
        return self

    def set_presubmit_yml(self, presubmit_yml):
        self.presubmit_yml = presubmit_yml
        return self

    def add_build_target(self, target):
        if not target.startswith("@" + self.name):
            target = "@" + self.name + target
        self.build_targets.append(target)
        return self

    def add_test_module_build_target(self, target):
        self.test_module_build_targets.append(target)
        return self

    def add_test_module_test_target(self, target):
        self.test_module_test_targets.append(target)
        return self

    def dump(self, file):
        json_dump(file, self.__dict__)

    def from_json(self, file):
        with open(file) as f:
            self.__dict__ = json.load(f)


class RegistryException(Exception):
    """
    Raised whenever something goes wrong with modifying the registry.
    """


class RegistryClient:
    """A class to help create a Bazel registry."""

    _MODULE_BAZEL = """
module(
    name = "{0}",
    version = "{1}",
    compatibility_level = {2},
)
""".strip()

    def __init__(self, root):
        self.root = pathlib.Path(root)

    def get_all_modules(self):
        modules_dir = self.root.joinpath("modules")
        return [path.name for path in modules_dir.iterdir()]

    def get_module_versions(self, module_name, include_yanked=True):
        module_versions = []
        metadata = self.get_metadata(module_name)
        for version in metadata["versions"]:
            if include_yanked or version not in metadata.get("yanked_versions", {}):
                module_versions.append((module_name, version))
        return module_versions

    def get_all_module_versions(self, include_yanked=True):
        module_versions = []
        for module_name in self.get_all_modules():
            module_versions.extend(self.get_module_versions(module_name, include_yanked))
        return module_versions

    def get_metadata(self, module_name):
        return json.loads(self.get_metadata_path(module_name).read_text())

    def get_metadata_path(self, module_name):
        return self.root / "modules" / module_name / "metadata.json"

    def get_module_dir(self, module_name):
        return self.root / "modules" / module_name

    def get_version_dir(self, module_name, version):
        return self.get_module_dir(module_name) / version

    def get_overlay_dir(self, module_name, version):
        return self.get_version_dir(module_name, version) / "overlay"

    def get_source(self, module_name, version):
        return json.loads(self.get_source_json_path(module_name, version).read_text())

    def get_source_json_path(self, module_name, version):
        return self.get_version_dir(module_name, version) / "source.json"

    def get_presubmit_yml_path(self, module_name, version):
        return self.get_version_dir(module_name, version) / PRESUBMIT_YML

    def get_patch_file_path(self, module_name, version, patch_name):
        return self.get_version_dir(module_name, version) / "patches" / patch_name

    def get_module_dot_bazel_path(self, module_name, version):
        return self.get_version_dir(module_name, version) / "MODULE.bazel"

    def get_attestations(self, module_name, version):
        path = self.get_version_dir(module_name, version) / "attestations.json"
        if not path.exists():
            return None

        return json.loads(path.read_text())

    def contains(self, module_name, version=None):
        """
        Check if the registry contains a module or a specific version of a
        module by verifying if the directory exists.
        """
        dir_path = self.root.joinpath("modules", module_name)
        if version:
            dir_path = dir_path.joinpath(version)
        return dir_path.is_dir()

    def init_module(self, module_name, maintainers, homepage, source_repository=""):
        """
        Initialize a module, create the directory and metadata.json file.

        Parameters
        ----------
        module_name : str
            The module name
        maintainers : list of maps of string -> string
            The maintainer information, eg
             [{"name": "John", "email": "john@guugoo.com"},
              {"name": "Yun", "github": "meteorcloudy"}]
        homepage : str
            A URL to the project's homepage

        """
        p = self.root.joinpath("modules", module_name)
        p.mkdir(parents=True, exist_ok=True)

        # Create metadata.json file
        metadata = {
            "maintainers": maintainers,
            "homepage": homepage,
            "repository": [source_repository] if source_repository else [],
            "versions": [],
            "yanked_versions": {},
        }
        json_dump(p.joinpath("metadata.json"), metadata)

    def add(self, module, override=False):
        """
        Add a new module version, the module must be already initialized

        Parameters
        ----------
        module : Module
            A Module instance containing information of the module version to
            be added
        override : Whether to override existing module
        """
        # Check if the module version already exists
        if self.contains(module.name, module.version):
            if override:
                log("Overriding module '%s' at version '%s'..." % (module.name, module.version))
                self.delete(module.name, module.version)
            else:
                raise RegistryException(f"Version {module.version} for module {module.name} already exists.")

        p = self.root.joinpath("modules", module.name, module.version)
        p.mkdir()

        # Create MODULE.bazel
        module_dot_bazel = p.joinpath("MODULE.bazel")
        if module.module_dot_bazel:
            # TODO(pcloudy): Sanity check the given MODULE.bazel
            #   - module name and version should match the specified values
            #   - no override is used
            shutil.copy(module.module_dot_bazel, module_dot_bazel)
        else:
            deps = "\n".join(f'bazel_dep(name = "{name}", version = "{version}")' for name, version in module.deps)
            with module_dot_bazel.open("w") as f:
                f.write(self._MODULE_BAZEL.format(module.name, module.version, module.compatibility_level))
                if deps:
                    f.write("\n")
                    f.write(deps)
                f.write("\n")

        # Create source.json & copy patch files to the registry
        source = {
            "url": module.url,
            "integrity": integrity(download(module.url)),
        }
        if module.strip_prefix:
            source["strip_prefix"] = module.strip_prefix

        patch_dir = p.joinpath("patches")
        if module.patches or module.build_file:
            patch_dir.mkdir()
            source["patches"] = {}
            source["patch_strip"] = module.patch_strip

        if module.patches:
            for s in module.patches:
                patch = pathlib.Path(s)
                source["patches"][patch.name] = integrity(read(patch))
                shutil.copy(patch, patch_dir)

        # Turn additional BUILD file into a patch
        if module.build_file:
            build_file_content = pathlib.Path(module.build_file).open().readlines()
            build_file = "a/" * module.patch_strip + "BUILD.bazel"
            patch_content = difflib.unified_diff([], build_file_content, "/dev/null", build_file)
            patch_name = "add_build_file.patch"
            patch = patch_dir.joinpath(patch_name)
            with patch.open("w") as f:
                f.writelines(patch_content)
            source["patches"][patch_name] = integrity(read(patch))

        json_dump(p.joinpath("source.json"), source, sort_keys=False)

        # Create presubmit.yml file
        presubmit_yml = p.joinpath(PRESUBMIT_YML)
        if module.presubmit_yml:
            shutil.copy(module.presubmit_yml, presubmit_yml)
        else:
            PLATFORMS = ["debian11", "ubuntu2204", "macos", "macos_arm64", "windows"]
            BAZEL_VERSIONS = ["8.x", "7.x", "6.x"]
            presubmit = {
                "matrix": {
                    "platform": PLATFORMS.copy(),
                    "bazel": BAZEL_VERSIONS.copy(),
                },
                "tasks": {
                    "verify_targets": {
                        "name": "Verify build targets",
                        "platform": "${{ platform }}",
                        "bazel": "${{ bazel }}",
                        "build_targets": module.build_targets.copy(),
                    }
                },
            }

            if module.test_module_path:
                task = {
                    "name": "Run test module",
                    "platform": "${{ platform }}",
                    "bazel": "${{ bazel }}",
                }
                if module.test_module_build_targets:
                    task["build_targets"] = module.test_module_build_targets.copy()
                if module.test_module_test_targets:
                    task["test_targets"] = module.test_module_test_targets.copy()
                presubmit["bcr_test_module"] = {
                    "module_path": module.test_module_path,
                    "matrix": {
                        "platform": PLATFORMS.copy(),
                        "bazel": BAZEL_VERSIONS.copy(),
                    },
                    "tasks": {"run_test_module": task},
                }

            with presubmit_yml.open("w") as f:
                yaml.dump(presubmit, f, sort_keys=False)

        # Add new version to metadata.json
        metadata_path = self.root.joinpath("modules", module.name, "metadata.json")
        metadata = json.load(metadata_path.open())
        metadata["versions"].append(module.version)
        metadata["versions"] = list(set(metadata["versions"]))
        metadata["versions"].sort(key=Version)
        json_dump(metadata_path, metadata)

    def update_versions(self, module_name):
        """Update the list of versions in the metadata.json."""
        module_path = self.root / "modules" / module_name
        versions = (v.name for v in module_path.iterdir() if v.is_dir())
        metadata = self.get_metadata(module_name)
        metadata["versions"] = sorted(versions, key=Version)
        metadata_path = self.get_metadata_path(module_name)
        json_dump(metadata_path, metadata)

    def update_integrity(self, module_name, version):
        """Update the SRI hashes of the source.json file of module at version."""
        source = self.get_source(module_name, version)
        source["integrity"] = integrity(download(source["url"]))
        source_path = self.get_source_json_path(module_name, version)

        patch_dir = source_path.parent / "patches"
        if patch_dir.exists():
            available = sorted(p.name for p in patch_dir.iterdir())
        else:
            available = []
        current = source.get("patches", {}).keys()
        patch_files = [patch_dir / p for p in current]
        patch_files.extend(patch_dir / p for p in available if p not in current)
        patches = {str(patch.relative_to(patch_dir)): integrity(read(patch)) for patch in patch_files}
        if patches:
            source["patches"] = patches
        else:
            source.pop("patches", None)

        overlay_dir = self.get_overlay_dir(module_name, version)
        overlay_files = []
        if overlay_dir.exists():
            overlay_files = sorted(
                [
                    p.relative_to(overlay_dir)
                    for p in overlay_dir.rglob("*")
                    if p.is_file() and p.name != "MODULE.bazel.lock"
                ]
            )
        overlay_integrities = {str(file): integrity(read(overlay_dir / file)) for file in overlay_files}
        if overlay_files:
            source["overlay"] = overlay_integrities
        else:
            source.pop("overlay", None)

        json_dump(source_path, source, sort_keys=False)

    def delete(self, module_name, version):
        """Delete an existing module version."""
        p = self.root.joinpath("modules", module_name)
        shutil.rmtree(p.joinpath(version))
        metadata_path = p.joinpath("metadata.json")
        metadata = json.load(metadata_path.open())
        if version in metadata["versions"]:
            metadata["versions"].remove(version)
        json_dump(metadata_path, metadata)


def _download_if_exists(url):
    try:
        return download(url)
    except urllib.error.HTTPError as ex:
        if ex.code == 404:
            return None

        raise RegistryException(f"Failed to read {url}: {ex.reason}")


class UpstreamRegistry:
    def __init__(self, modules_dir_url):
        self._root_url = modules_dir_url

    def get_latest_module_version(self, module_name):
        metadata_url = posixpath.join(self._root_url, module_name, "metadata.json")
        content = _download_if_exists(metadata_url)
        if not content:
            return None

        metadata = json.loads(content)
        latest_version = metadata["versions"][-1]  # Presubmit ensures asc. order
        module_root_url = posixpath.join(self._root_url, module_name, latest_version)
        return ModuleSnapshot(latest_version, module_root_url)


class ModuleSnapshot:
    def __init__(self, version, root_url):
        self.version = version
        self._root_url = root_url

    def _download_if_exists(self, filename):
        return _download_if_exists(posixpath.join(self._root_url, filename))

    def presubmit_yml_lines(self):
        raw = self._download_if_exists(PRESUBMIT_YML)
        if not raw:
            return None

        return raw.decode("utf-8").splitlines(keepends=True)

    def attestations(self):
        raw = self._download_if_exists("attestations.json")
        if raw:
            return json.loads(raw)

    def module_dot_bazel(self):
        raw = self._download_if_exists(MODULE_DOT_BAZEL)
        if not raw:
            return None

        return raw.decode("utf-8")
