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

{ depot, lib, pkgs, ... }:
let
  cfg = let
    macOS = system: {
      stage = "build";
      image = "nixos/nix:latest";
      script = [
        "nix run -f ./ third_party.nixpkgs.bash -- ./hack/populate_secrets.sh"
        "nix build -v -f ./ci-root.nix --system ${system} --argstr system ${system} --substituters \"https://cache.nixos.org/ s3://lukegb-nix-cache?endpoint=storage.googleapis.com&trusted=1\""
        "nix copy -v --to 's3://lukegb-nix-cache?endpoint=storage.googleapis.com' ./result"
      ];
      timeout = "6h";
      allow_failure = true;
      tags = [ "macos" ];
    };
    linux-eval = {
      stage = "build";
      image = "nixos/nix:latest";
      script = [
        "nix run -f ./ third_party.nixpkgs.bash -- ./hack/populate_secrets.sh"
        "nix-instantiate ./ci-root-linux.nix --option substituters \"https://cache.nixos.org/ s3://lukegb-nix-cache?endpoint=storage.googleapis.com&trusted=1\" > drv-name"
        "cat drv-name"
        "ln -s $(cat drv-name) ./result"
        "nix run -f ./ go.nix.bcacheup -- --cache_url vaultgs://lukegb-nix-cache --vault_addr unix:///run/tokend/sock --vault_token_source gcp/roleset/binary-cache-deployer/token ./result"
      ];
      artifacts = {
        paths = [ "drv-name" ];
        expire_in = "30 days";
      };
      tags = [ "cacher" ];
    };
    linux-combined = {
      stage = "build";
      image = "nixos/nix:latest";
      needs = [{ job = "nixCache-linux-eval"; artifacts = true; }];
      script = [
        "for n in 1 2 3 4 5; do echo attempt $n; nix-store --realise $(cat drv-name) --option substituters \"https://cache.nixos.org/ s3://lukegb-nix-cache?endpoint=storage.googleapis.com&trusted=1\" --indirect --add-root ./result && break; done"
        "readlink -f ./result"
        "nix run -f ./ go.nix.bcacheup -- --cache_url vaultgs://lukegb-nix-cache --vault_addr unix:///run/tokend/sock --vault_token_source gcp/roleset/binary-cache-deployer/token ./result"
        "cat ./result/combined-systems > systems.json"
      ];
      timeout = "6h";
      artifacts = {
        paths = [ "systems.json" "hack/populate_secrets.sh" "hack/deploy.sh" ];
        expire_in = "30 days";
      };
      tags = [ "cacher" ];
    };
  in {
    stages = [ "build" "deploy-mach" "deploy-other" ];

    nixCache-linux-eval = linux-eval;
    nixCache-linux = linux-combined;
    nixCache-x86_64-darwin = macOS "x86_64-darwin";
    nixCache-aarch64-darwin = macOS "aarch64-darwin";

    flipperzero-firmware = {
      stage = "deploy-other";
      needs = [{ job = "nixCache-linux"; artifacts = false; }];
      tags = [ "cacher" ];
      only.refs = [ "branch/default" ];

      script = ''
        export NIX_PATH=nixpkgs=$(readlink -f hack/nixpkgs)
        $(nix-build -A nix.pkgs.flipperzero-firmware.upload)/bin/upload-f0
      '';
    };
    lukegbcom = {
      stage = "deploy-other";
      needs = [{ job = "nixCache-linux"; artifacts = false; }];
      tags = [ "cacher" ];
      only.refs = [ "branch/default" ];

      script = ''
        export NIX_PATH=nixpkgs=$(readlink -f hack/nixpkgs)
        cd web/lukegbcom
        ./deploy.sh
      '';
    };
  } // (lib.mapAttrs deployStage deployMachs);

  deployMachs = lib.filterAttrs (name: cfg: cfg.config.my.deploy.enable) depot.ops.nixos.systemConfigs;
  deployStage = machName: mach: ({
    stage = "deploy-mach";
    needs = [{ job = "nixCache-linux"; artifacts = true; }];
    tags = [ "deployer" ];

    resource_group = machName;
    script = ''./hack/deploy.sh "${machName}" "${mach.config.my.deploy.args}"'';
    environment = {
      name = machName;
    };
    variables = {
      GIT_STRATEGY = "none";
    };
    allow_failure = true;

    only.refs = [ "branch/default" ];
  } // lib.optionalAttrs (!mach.config.my.deploy.enable) {
    when = "manual";
  });

  format = pkgs.formats.yaml { };
  configFile = format.generate ".gitlab-ci.yml" cfg;
in
  configFile