#!/usr/bin/env python3
# Copyright (C) 2020 The Android Open Source Project
#
# 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.

"""Helper tool for signing repo launcher scripts correctly.

This is intended to be run only by the official Repo release managers.
"""

import argparse
import os
import re
import subprocess
import sys

import util


def sign(opts):
    """Sign the launcher!"""
    output = ""
    for key in opts.keys:
        # We use ! at the end of the key so that gpg uses this specific key.
        # Otherwise it uses the key as a lookup into the overall key and uses
        # the default signing key.  i.e. It will see that KEYID_RSA is a subkey
        # of another key, and use the primary key to sign instead of the subkey.
        cmd = [
            "gpg",
            "--homedir",
            opts.gpgdir,
            "-u",
            f"{key}!",
            "--batch",
            "--yes",
            "--armor",
            "--detach-sign",
            "--output",
            "-",
            opts.launcher,
        ]
        ret = util.run(opts, cmd, encoding="utf-8", stdout=subprocess.PIPE)
        output += ret.stdout

    # Save the combined signatures into one file.
    with open(f"{opts.launcher}.asc", "w", encoding="utf-8") as fp:
        fp.write(output)


def check(opts):
    """Check the signature."""
    util.run(opts, ["gpg", "--verify", f"{opts.launcher}.asc"])


def get_version(opts):
    """Get the version from |launcher|."""
    # Make sure we don't search $PATH when signing the "repo" file in the cwd.
    launcher = os.path.join(".", opts.launcher)
    cmd = [launcher, "--version"]
    ret = util.run(opts, cmd, encoding="utf-8", stdout=subprocess.PIPE)
    m = re.search(r"repo launcher version ([0-9.]+)", ret.stdout)
    if not m:
        sys.exit(f"{opts.launcher}: unable to detect repo version")
    return m.group(1)


def postmsg(opts, version):
    """Helpful info to show at the end for release manager."""
    print(
        f"""
Repo launcher bucket:
  gs://git-repo-downloads/

You should first upload it with a specific version:
  gsutil cp -a public-read {opts.launcher} gs://git-repo-downloads/repo-{version}
  gsutil cp -a public-read {opts.launcher}.asc gs://git-repo-downloads/repo-{version}.asc

Then to make it the public default:
  gsutil cp -a public-read gs://git-repo-downloads/repo-{version} gs://git-repo-downloads/repo
  gsutil cp -a public-read gs://git-repo-downloads/repo-{version}.asc gs://git-repo-downloads/repo.asc

NB: If a rollback is necessary, the GS bucket archives old versions, and may be
    accessed by specifying their unique id number.
  gsutil ls -la gs://git-repo-downloads/repo gs://git-repo-downloads/repo.asc
  gsutil cp -a public-read gs://git-repo-downloads/repo#<unique id> gs://git-repo-downloads/repo
  gsutil cp -a public-read gs://git-repo-downloads/repo.asc#<unique id> gs://git-repo-downloads/repo.asc
"""  # noqa: E501
    )


def get_parser():
    """Get a CLI parser."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        "-n",
        "--dry-run",
        dest="dryrun",
        action="store_true",
        help="show everything that would be done",
    )
    parser.add_argument(
        "--gpgdir",
        default=os.path.join(util.HOMEDIR, ".gnupg", "repo"),
        help="path to dedicated gpg dir with release keys "
        "(default: ~/.gnupg/repo/)",
    )
    parser.add_argument(
        "--keyid",
        dest="keys",
        default=[],
        action="append",
        help="alternative signing keys to use",
    )
    parser.add_argument(
        "launcher",
        default=os.path.join(util.TOPDIR, "repo"),
        nargs="?",
        help="the launcher script to sign",
    )
    return parser


def main(argv):
    """The main func!"""
    parser = get_parser()
    opts = parser.parse_args(argv)

    if not os.path.exists(opts.gpgdir):
        parser.error(f"--gpgdir does not exist: {opts.gpgdir}")
    if not os.path.exists(opts.launcher):
        parser.error(f"launcher does not exist: {opts.launcher}")

    opts.launcher = os.path.relpath(opts.launcher)
    print(
        f'Signing "{opts.launcher}" launcher script and saving to '
        f'"{opts.launcher}.asc"'
    )

    if opts.keys:
        print(f'Using custom keys to sign: {" ".join(opts.keys)}')
    else:
        print("Using official Repo release keys to sign")
        opts.keys = [util.KEYID_DSA, util.KEYID_RSA, util.KEYID_ECC]
        util.import_release_key(opts)

    version = get_version(opts)
    sign(opts)
    check(opts)
    postmsg(opts, version)

    return 0


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
