# checkout nixos/modules/services/continuous-integration/gitlab-runner.nix to
# check how the config is generated/service run
# For all options not available, just use "registrationFlags"
{
  modulesPath,
  pkgs,
  lib,
  ...
}@attrs:
let
  gitlabUrl = "https://git.novadiscovery.net/";

  defaultRegistrationFlags = [
    "--url ${gitlabUrl}"
    "-r $(cat /run/secrets/gitlab/registrationToken)"
  ];
  runnerName = "devs";
  targetEnvironment = "aws";
  # novaLib = pkgs.callPackage ./lib.nix { inherit runnerName targetEnvironment; };

  # a function to rename tags depending on the environment
  renameTag = tag: if targetEnvironment == "dev" then "test_${tag}" else tag;

  # for now let's avoid using quotes
  genDescription = name: "MATTs machine !! ${name} ${targetEnvironment} - ${runnerName}";
in
{
  # Gitlab Runner
  # https://nixos.wiki/wiki/Gitlab_runner
  boot.kernel.sysctl."net.ipv4.ip_forward" = true; # 1

  services.gitlab-runner = {
    enable = true;
    # settings = {
    #   checkInterval = 0;
    #   concurrent = 100;
    # };
    # gracefulTermination = true;
    # debugTraceDisabled # set to true Runner will disable the possibility of using the CI_DEBUG_TRACE
    # gracefulTimeout = "5min 20s";

    services = {

      nix = {
        description = genDescription "Nix/Bazel 2";
        limit = 10;
        executor = "docker";
        # registrationConfigFile is mandatory so forward it to /dev/null
        registrationConfigFile = "/dev/null";
        registrationFlags = defaultRegistrationFlags ++ [ "--docker-memory 32G" ];
        dockerPrivileged = true;

        # copied from nixpkgs' gitlab-runner module default
        dockerImage = "alpine";
        dockerVolumes = [
          "/nix/store:/nix/store:ro"
          "/nix/var/nix/db:/nix/var/nix/db"
          "/nix/var/nix/daemon-socket:/nix/var/nix/daemon-socket"
          "bazel-runtime:/tmp/.cache/bazel"
          # bind it to help applications in the container find the AWS credentials
          "/run/secrets/aws/credentialsFile:/root/.aws/credentials:ro"
        ];
        dockerDisableCache = true;

        preBuildScript = pkgs.writeScript "setup-container" ''
          mkdir -p -m 0755 /nix/var/log/nix/drvs
          mkdir -p -m 0755 /nix/var/nix/gcroots
          mkdir -p -m 0755 /nix/var/nix/profiles
          mkdir -p -m 0755 /nix/var/nix/temproots
          mkdir -p -m 0755 /nix/var/nix/userpool
          mkdir -p -m 1777 /nix/var/nix/gcroots/per-user
          mkdir -p -m 1777 /nix/var/nix/profiles/per-user
          mkdir -p -m 0755 /nix/var/nix/profiles/per-user/root
          mkdir -p -m 0700 "$HOME/.nix-defexpr"

          . ${pkgs.nix}/etc/profile.d/nix.sh

          # nix-env installs in NIX_PROFILE or /nix/var/nix/profiles/default (see manpage)
          ${pkgs.nix}/bin/nix-env -i ${
            lib.concatStringsSep " " (
              with pkgs;
              [
                nix
                cacert
                git
                openssh
              ]
            )
          }

          cp "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" /etc/ssl/certs/ca-certificates.crt
          mkdir -p ~/.config/nix
          echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf

        '';

        environmentVariables =
          let
            paths = [
              "/nix/var/nix/profiles/default/bin"
              "/nix/var/nix/profiles/default/sbin"
              "/nix/var/nix/profiles/per-user/root/profile/bin"
              "/nix/var/nix/profiles/per-user/ubuntu/profile/bin"
              "/bin"
              "/sbin"
              "/usr/bin"
              "/usr/sbin"
            ];
          in
          {
            DOCKER_DRIVER = "overlay2";
            ENV = "/etc/profile";
            USER = "root";
            NIX_REMOTE = "daemon";
            # This is one tricky part: to speed up the build process, we mount the host nix store in the docker container but as docker images
            # contain symlinks towards the /nix store, those symlinks can be broken if they dont exist in the host store
            # For instance the docker image generated by:
            # - nix build github:nixos/nix#dockerImage : has /bin/sh -> /nix/store/.../bash
            #
            # /nix/var/nix/profiles/default/bin matches nix-env for root: this works fine on a nixos-deployed runner but
            # we also have ubuntu-based machines
            # /nix/var/nix/profiles/per-user/ubuntu/profile/bin
            PATH = lib.concatStringsSep ":" paths;
            # This is the default in the gitlab-runner module ?!
            # NIX_SSL_CERT_FILE = "/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt";
            NIX_SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
            SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";

          };

        tagList = [
          (renameTag "nix")
          (renameTag "bazel")
          "nixos"
          runnerName
        ];
      };

    };
  };

  # has to be deployed on
  systemd.services.gitlab-runner = {
    after = [ "run-secrets.d.mount" ];
    requires = [ "run-secrets.d.mount" ];
  };
}
