#!/usr/bin/env python3

"""
A wrapper to convert `sigstore-conformance` CLI protocol invocations to match `sigstore-python`.
"""

import json
import os
import sys
from contextlib import suppress
from tempfile import NamedTemporaryFile

# The signing config in this trust_config is not used: it's just here
# so the built trustconfig is complete
trust_config = {
    "mediaType": "application/vnd.dev.sigstore.clienttrustconfig.v0.1+json",
    "signingConfig": {
        "mediaType": "application/vnd.dev.sigstore.signingconfig.v0.2+json",
        "caUrls": [{
            "url": "https://fulcio.example.com",
            "majorApiVersion": 1,
            "operator": "",
            "validFor": {"start": "1970-01-01T01:01:01Z"}
        }],
        "oidcUrls": [],
        "rekorTlogUrls": [{
            "url": "https://rekor.example.com",
            "majorApiVersion": 1,
            "operator": "",
            "validFor": {"start": "1970-01-01T01:01:01Z"}
        }],
        "tsaUrls": [],
        "rekorTlogConfig": {"selector": "ANY"},
        "tsaConfig": {"selector": "ANY"},
    },
}

SUBCMD_REPLACEMENTS = {
    "sign-bundle": "sign",
    "verify-bundle": "verify",
}

ARG_REPLACEMENTS = {
    "--certificate-identity": "--cert-identity",
    "--certificate-oidc-issuer": "--cert-oidc-issuer",
}

# Trim the script name.
fixed_args = sys.argv[1:]

# Substitute incompatible subcommands.
subcmd = fixed_args[0]
if subcmd in SUBCMD_REPLACEMENTS:
    fixed_args[0] = SUBCMD_REPLACEMENTS[subcmd]

# Build base command with optional staging argument
command = ["sigstore"]
if "--staging" in fixed_args:
    command.append("--staging")
    fixed_args.remove("--staging")

# We may get "--trusted-root" and "--signing-config" as argument but sigstore-python
# wants "--trust-config":
trusted_root_path = None
with suppress(ValueError):
    i = fixed_args.index("--trusted-root")
    trusted_root_path = fixed_args[i + 1]
    fixed_args.pop(i)
    fixed_args.pop(i)

signing_config_path = None
with suppress(ValueError):
    i = fixed_args.index("--signing-config")
    signing_config_path = fixed_args[i + 1]
    fixed_args.pop(i)
    fixed_args.pop(i)


# If we did get a trustedroot, write a matching trustconfig into a temp file
# Use given signingconfig if possible, otherwise use the fake one in template
with NamedTemporaryFile(mode="wt") as temp_file:
    if trusted_root_path is not None:
        with open(trusted_root_path) as f:
            trusted_root = json.load(f)
        trust_config["trustedRoot"] = trusted_root
        if signing_config_path is not None:
            with open(signing_config_path) as f:
                signing_config = json.load(f)
            trust_config["signingConfig"] = signing_config

        json.dump(trust_config, temp_file)
        temp_file.flush()

        command.extend(["--trust-config", temp_file.name])

    # Fix-up the subcommand: the conformance suite uses `verify`, but
    # `sigstore` requires `verify identity` for identity based verifications.
    subcommand, *fixed_args = fixed_args
    if subcommand == "sign":
        command.append("sign")
    elif subcommand == "verify":
        command.extend(["verify", "identity"])
    else:
        raise ValueError(f"unsupported subcommand: {subcommand}")

    # Replace incompatible flags.
    command.extend(
        ARG_REPLACEMENTS[arg] if arg in ARG_REPLACEMENTS else arg for arg in fixed_args
    )

    os.execvp("sigstore", command)
