# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0

{ lib, pkgs, depot, ... }:
let
  vault = pkgs.vault-bin;

  imageName = "europe-docker.pkg.dev/lukegb-vault/lukegb-vault/vault";
  imageVersion = vault.version;

  plugins = {
    acme = { pkg = depot.nix.pkgs.vault-acme; type = "secret"; name = "acme"; };
  };

  pluginDrv = pkgs.runCommand "vault-plugins" {} ''
    mkdir -p $out/libexec/vault

    ${lib.concatStrings (lib.mapAttrsToList (
      execName: pluginAttrs: ''
        cp ${pluginAttrs.pkg}/libexec/vault/${execName} $out/libexec/vault/${execName}
      ''
    ) plugins)}
  '';

  container = pkgs.dockerTools.buildImage rec {
    name = imageName;
    tag = imageVersion;

    copyToRoot = pluginDrv;

    # Using vault-bin because I want the vault UI.
    config.Entrypoint = [ "${vault}/bin/vault" "server" "-config" "/etc/vault/config.hcl" ];
    config.Env = [ "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" ];
  } // {
    plugins = pluginDrv;
  };

  updateVaultPluginsCmd = pkgs.runCommand "update-vault-plugins" {} ''
    mkdir -p $out/bin

    cat <<EOF >"$out/bin/update-vault-plugins"
    #!${pkgs.runtimeShell}
    set -o errexit
    set -o nounset
    set -o pipefail

    export VAULT_ADDR=https://vault.int.lukegb.com/

    vault token lookup >/dev/null || vault login -method=oidc role="admin" skip_browser=true

    ${lib.concatStrings (lib.mapAttrsToList (
      execName: pluginAttrs: ''
        echo '${execName}'
        vault write '/sys/plugins/catalog/${pluginAttrs.type}/${pluginAttrs.name}' command="${execName}" sha256="$(sha256sum '${pluginAttrs.pkg}/libexec/vault/${execName}' | cut -f1 -d' ')"
      ''
    ) plugins)}
    EOF
    chmod +x "$out/bin/update-vault-plugins"

    ${pkgs.stdenv.shellDryRun} "$out/bin/update-vault-plugins"
    ${pkgs.shellcheck}/bin/shellcheck "$out/bin/update-vault-plugins"
  '';

  uploadCmd = pkgs.writeShellApplication {
    name = "upload-vault-container";

    runtimeInputs = with pkgs; [ skopeo google-cloud-sdk ];

    text = ''
      echo
      echo Uploading ${imageName}:${imageVersion}
      skopeo copy docker-archive:${container} docker://${imageName}:${imageVersion}

      echo
      echo Switching Cloud Run over
      gcloud --project lukegb-vault run deploy vault-server --region europe-west1 --image ${imageName}:${imageVersion} --concurrency default

      echo
      echo Updating Vault SHA256 for plugins
      ${updateVaultPluginsCmd}/bin/update-vault-plugins
    '';
  };
in container // {
  upload = uploadCmd;
  updateVaultPlugins = updateVaultPluginsCmd;
}