# 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.

import subprocess

import gnupg


ENCRYPTED_KEYS = [
    "accessToken",
    "apiUrl",
    "caCert",
    "cert",
    "htpasswd",
    "issuer",
    "key",
    "password",
    "secret",
]


def _pgp(pgp_identifier, config_path):
    gpg = gnupg.GPG()
    gpg_keys = gpg.list_keys()
    selected_keys = list(
        filter(
            lambda k: pgp_identifier in k["fingerprint"]
            or pgp_identifier in k["keyid"]
            or len([v for v in k["uids"] if pgp_identifier in v]) > 0,
            gpg_keys,
        )
    )

    if not selected_keys:
        raise ValueError("PGP key not found.")

    if len(selected_keys) > 1:
        raise ValueError("Identifier of PGP not unique.")

    command = [
        "sops",
        "--encrypt",
        "--in-place",
        "--encrypted-regex",
        f"({'|'.join(ENCRYPTED_KEYS)})",
        "--pgp",
        selected_keys[0]["fingerprint"],
        config_path,
    ]
    subprocess.check_output(command)


def _vault(vault_address, engine, key, config_path):
    url = f"{vault_address}/v1/{engine}/keys/{key}"

    command = [
        "sops",
        "--encrypt",
        "--in-place",
        "--encrypted-regex",
        f"({'|'.join(ENCRYPTED_KEYS)})",
        "--hc-vault-transit",
        url,
        config_path,
    ]
    subprocess.check_output(command)


def encrypt(
    method, config_path, pgp_identifier=None, vault_address=None, engine=None, key=None
):
    """Encrypt the config file

    Args:
        method {string}: The method of receiving the encryption key.
            (options: 'pgp', 'vault')
        config_path {string}: The path to the config file to be encrypted
        pgp_identifier ({string}, optional): A unique identifier of the PGP key
            to be used. This can be the fingerprint, keyid or part of the uid
            (e.g. the email address). Required for method 'pgp'. Defaults to None.
        vault_address ({string}, optional): Base URL of Vault incl. protocol.
            Required for method 'vault'. Defaults to None.
        engine ({string}, optional): Name of the secret engine. Required for
            method 'vault'. Defaults to None.
        key ({string}, optional): Name of the key. Required for method 'vault'.
            Defaults to None.
    """
    if method == "pgp":
        if pgp_identifier is None:
            raise ValueError("Missing PGP identifier.")
        _pgp(pgp_identifier, config_path)
    elif method == "vault":
        if None in [vault_address, engine, key]:
            raise ValueError("Missing required metadata for accessing vault.")
        _vault(vault_address, engine, key, config_path)
    else:
        raise ValueError("Unknown method to retrieve key for encryption.")
