#!/usr/bin/env python3
#
# Copyright 2018 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=line-too-long
# pylint: disable=missing-function-docstring
# pylint: disable=unspecified-encoding
# pylint: disable=invalid-name
"""The CI script for Bazel Central Registry Postsubmit.

This script does one thing:
  - Sync the bazel_registry.json and modules/ directory in the main branch of the BCR to https://bcr.bazel.build
"""

import base64
import hashlib
import json
import os
import requests
import subprocess
import sys
import tempfile

BCR_BUCKET = "gs://bcr.bazel.build/"
ATTESTATION_METADATA_FILE = "attestations.json"
FILES_WITH_ATTESTATIONS = ("source.json", "MODULE.bazel")

# Basename of the file that contains the most recent commit
# that passed through the post-submit pipeline successfully.
LAST_GREEN_FILE = "last_green.txt"


class AttestationError(Exception):
    """Raised when there is a problem wrt attestations."""

def print_expanded_group(name):
    print("\n\n+++ {0}\n\n".format(name))

def get_output(command):
    return subprocess.run(
          command,
          encoding='utf-8',
          stdout=subprocess.PIPE,
      ).stdout

def check_and_write_new_attestations():
    print_expanded_group(":cop::copybara: Check & write attestations")
    paths = get_new_attestations_json_paths()
    if not paths:
        # TODO: turn this into an error
        print(f"No {ATTESTATION_METADATA_FILE} files were changed.")
        return

    for p in paths:
        check_and_write_module_attestations(p)


def get_new_attestations_json_paths():
    cwd = os.getcwd()
    cmd = ["git", "diff-tree", "--no-commit-id", "--name-only", "-r"]

    # last_green should be the parent commit. However, sometimes the
    # pipeline can fail due to infra issues. In this case we need
    # to mirror attestations in the commits of the failing runs, too.
    last_green = get_last_green()
    if last_green:
        cmd.append(last_green)

    paths = get_output(cmd + [get_commit()])
    return [os.path.join(cwd, p) for p in paths.split("\n") if p.endswith(f"/{ATTESTATION_METADATA_FILE}")]


def get_last_green():
    url = os.path.join(
        BCR_BUCKET.replace("gs://", "https://storage.googleapis.com/"), LAST_GREEN_FILE
    )
    with requests.get(url) as response:
        if response.status_code != 200:
            return ""

        return response.content.decode("utf-8")


def get_commit():
    return os.getenv("BUILDKITE_COMMIT")


def check_and_write_module_attestations(attestations_json_path):
    print(f"Checking {attestations_json_path}...")
    dest_dir = os.path.dirname(attestations_json_path)
    with open(attestations_json_path, "rb") as af:
        metadata = json.loads(af.read())
    
    for f in FILES_WITH_ATTESTATIONS:
        try:
            entry = metadata["attestations"][f]
            check_and_write_single_attestation(entry["url"], entry["integrity"], dest_dir)
        except Exception as ex:
            raise AttestationError(f"{attestations_json_path} - {f}: {ex}") from ex

    print("Done!")

def check_and_write_single_attestation(url, integrity, dest_dir):
    print(f"\tFound attestation @ {url}")
    with requests.get(url) as response:
        if response.status_code != 200:
            raise AttestationError(f"{url}: HTTP {response.status_code}")

        raw_content = response.content

    check_integrity(raw_content, integrity)
    print("\t\tIntegrity: OK")

    dest = os.path.join(dest_dir, get_canonical_basename(url))
    print(f"\t\tWriting attestation to {dest}...")
    with open(dest, "wb") as f:
        f.write(raw_content)

def check_integrity(data, expected):
    algorithm, _, _ = expected.partition("-")
    assert algorithm in {"sha224", "sha256", "sha384", "sha512"}, "Unsupported SRI algorithm"

    hash = getattr(hashlib, algorithm)(data)
    encoded = base64.b64encode(hash.digest()).decode()
    actual = f"{algorithm}-{encoded}"
    if actual != expected:
        raise AttestationError(f"Expected checksum {expected}, got {actual}.")

# Attestation files in GitHub releases may have prefixes in their basename
# to avoid conflicts when multiple modules are released together
# (e.g. rules_python and rules_python_gazelle_plugin).
# In this case we need to get the canonical basename.
def get_canonical_basename(url):
    actual_basename = os.path.basename(url)
    for f in FILES_WITH_ATTESTATIONS:
        if f in actual_basename:
            return f"{f}.intoto.jsonl"
    
    raise AttestationError(f"Invalid basename of {url}.")


def sync_bcr_content():
    print_expanded_group(":gcloud: Sync BCR content")
    subprocess.check_output(
        ["gsutil", "-h", "Cache-Control:no-cache", "cp", "./bazel_registry.json", BCR_BUCKET]
    )
    subprocess.check_output(
        ["gsutil", "-h", "Cache-Control:no-cache", "-m", "rsync", "-r", "./modules", BCR_BUCKET + "modules"]
    )


def update_last_green():
    path = os.path.join(tempfile.mkdtemp(), LAST_GREEN_FILE)
    with open(path, "wt") as f:
        f.write(get_commit())

    dest = os.path.join(BCR_BUCKET, LAST_GREEN_FILE)
    subprocess.check_output(["gsutil", "cp", path, dest])


def main():
    check_and_write_new_attestations()
    sync_bcr_content()
    update_last_green()
    return 0

if __name__ == "__main__":
    sys.exit(main())
