{
  lib,
  config,
  pkgs,
  ...
}:
let
  cfg = config.services.my-hydra;
  toSpec =
    {
      name,
      owner,
      ...
    }:
    let
      spec = {
        enabled = 1;
        hidden = false;
        description = "Declarative specification jobset automatically generated";
        checkinterval = 120;
        schedulingshares = 10000;
        enableemail = false;
        emailoverride = "";
        keepnr = 1;
        nixexprinput = "src";
        nixexprpath = "jobsets.nix";
        inputs = {
          src = {
            type = "path";
            value = pkgs.writeTextFile {
              name = "src";
              text = builtins.readFile ./jobsets.nix;
              destination = "/jobsets.nix";
            };
            emailresponsible = false;
          };
          repoInfoPath = {
            type = "path";
            value = pkgs.writeTextFile {
              name = "repo";
              text = builtins.toJSON {
                inherit name owner;
              };
            };
            emailresponsible = false;
          };
          prs = {
            type = "githubpulls";
            value = "${owner} ${name}";
            emailresponsible = false;
          };
        };
      };
      drv = pkgs.writeTextFile {
        name = "hydra-jobset-specification-${name}";
        text = builtins.toJSON spec;
        destination = "/spec.json";
      };
    in
    "${drv}";
in
{
  imports = [
    ./config.nix
    ../nginx-base
  ];

  options.services.my-hydra = {
    domain = lib.mkOption {
      type = lib.types.str;
      default = "hydra.aciceri.dev";
    };
    repos = lib.mkOption {
      type = lib.types.attrsOf (
        lib.types.submodule (
          {
            name,
            config,
            ...
          }:
          {
            options = {
              name = lib.mkOption {
                type = lib.types.str;
                default = name;
              };
              owner = lib.mkOption {
                type = lib.types.str;
                default = "aciceri";
              };
              description = lib.mkOption {
                type = lib.types.str;
                default = config.homepage;
              };
              homepage = lib.mkOption {
                type = lib.types.str;
                default = "https://github.com/${config.owner}/${config.name}";
              };
              reportStatus = lib.mkOption {
                type = lib.types.bool;
                default = true;
              };
            };
          }
        )
      );
      default = { };
    };
  };

  config = {
    # TODO manage `hydra` user ssh key declaratively
    nix.extraOptions = ''
      allowed-uris = https://github.com/ git://git.savannah.gnu.org/ https://git.sr.ht
    '';

    services.hydra-dev = {
      enable = true;
      hydraURL = "https://${cfg.domain}";
      notificationSender = "hydra@mothership.fleet";
      useSubstitutes = true;
      extraConfig =
        ''
          <github_authorization>
          include ${config.age.secrets.hydra-github-token.path}
          </github_authorization>
        ''
        + (lib.concatMapStrings (
          repo:
          lib.optionalString repo.reportStatus ''
            <githubstatus>
              jobs = ${repo.name}.*
              excludeBuildFromContext = 1
              useShortContext = 1
            </githubstatus>
          ''
        ) (builtins.attrValues cfg.repos));
    };

    systemd.services.hydra-setup = {
      description = "Hydra CI setup";
      serviceConfig.Type = "oneshot";
      serviceConfig.RemainAfterExit = true;
      wantedBy = [ "multi-user.target" ];
      requires = [ "hydra-init.service" ];
      after = [ "hydra-init.service" ];
      environment = builtins.removeAttrs (config.systemd.services.hydra-init.environment) [ "PATH" ];
      script =
        ''
          PATH=$PATH:${
            lib.makeBinPath (
              with pkgs;
              [
                yq-go
                curl
                config.services.hydra.package
              ]
            )
          }
          PASSWORD="$(cat ${config.age.secrets.hydra-admin-password.path})"
          if [ ! -e ~hydra/.setup-is-complete ]; then
            hydra-create-user admin \
              --full-name "Andrea Ciceri" \
              --email-address "andrea.ciceri@autistici.org" \
              --password "$PASSWORD" \
              --role admin
            touch ~hydra/.setup-is-complete
          fi

          mkdir -p /var/lib/hydra/.ssh
          cp /home/ccr/.ssh/id_rsa* /var/lib/hydra/.ssh/
          chown -R hydra:hydra /var/lib/hydra/.ssh

          mkdir -p /var/lib/hydra/queue-runner/.ssh
          cp /home/ccr/.ssh/id_rsa* /var/lib/hydra/queue-runner/.ssh/
          chown -R hydra-queue-runner:hydra /var/lib/hydra/queue-runner/.ssh

          curl --head -X GET --retry 5 --retry-connrefused --retry-delay 1 http://localhost:3000

          CURRENT_REPOS=$(curl -s -H "Accept: application/json" http://localhost:3000 | yq ".[].name")
          DECLARED_REPOS="${lib.concatStringsSep " " (builtins.attrNames cfg.repos)}"

          curl -H "Accept: application/json" \
            -H 'Origin: http://localhost:3000' \
            -H 'Content-Type: application/json' \
            -d "{\"username\": \"admin\", \"password\": \"$PASSWORD\"}" \
            --request "POST" localhost:3000/login \
            --cookie-jar cookie

          for repo in $CURRENT_REPOS; do
            echo $repo
            [[ ! "$DECLARED_REPOS" =~ (\ |^)$repo(\ |$) ]] && \
              curl -H "Accept: application/json" \
                --request "DELETE" \
                --cookie cookie \
                http://localhost:3000/project/$repo
          done
        ''
        + lib.concatMapStrings (repo: ''
          curl -H "Accept: application/json" \
            -H 'Content-Type: application/json' \
            --request "PUT" \
            localhost:3000/project/${repo.name} \
            --cookie cookie \
            -d '{
              "name": "${repo.name}",
              "displayname": "${repo.name}",
              "description": "${repo.description}",
              "homepage": "${repo.homepage}",
              "owner": "admin",
              "enabled": true,
              "visible": true,
              "declarative": {
                "file": "spec.json",
                "type": "path",
                "value": "${toSpec repo}"
              }
            }'
        '') (builtins.attrValues cfg.repos)
        + ''
          rm cookie
        '';
    };

    services.nginx.virtualHosts."${cfg.domain}" = {
      forceSSL = true;
      enableACME = true;
      locations."/" = {
        proxyPass = "http://127.0.0.1:${builtins.toString config.services.hydra.port}";
      };
    };
  };
}