{ pkgs, lib, config, ... }:
let
  inherit (config.services) sourcehut;
  inherit (config.users) users;
  inherit (config.security) gnupg;
  domain = "sourcephile.wg";
  sourcehut-services = [
    "builds"
    "dispatch"
    "git"
    "hg"
    "hub"
    "lists"
    "meta"
    "man"
    "paste"
    "pages"
    "todo"
  ];
in
{
  #boot.isContainer = true;
  #networking.firewall.allowedTCPPorts = [ 80 ];
  networking.hosts = {
    "192.168.42.2" = [ domain ] ++ map (d: "${d}.${domain}") sourcehut-services;
  };
  networking.nftables.ruleset = ''
    table inet filter {
      chain output-net {
        skuid ${sourcehut.meta.user} \
          tcp dport smtp counter \
          accept comment "sourcehut: SMTP"
      }
    }
  '';
  security.gnupg.secrets = lib.genAttrs [
    "sourcehut/network-key"
    "sourcehut/service-key"
    "sourcehut/webhook-key"
    "sourcehut/oauth-client-secret"
  ]
    (_p: {
      systemdConfig.before = [ "metasrht.service" "gitsrht.service" ];
      systemdConfig.wantedBy = [ "metasrht.service" "gitsrht.service" ];
    });
  services.minio = {
    enable = true;
    accessKey = "12345";
    secretKey = "12345678";
    #region = "";
    browser = true;
  };
  environment.systemPackages = [ pkgs.minio-client ];
  services.sourcehut = {
    enable = true;
    listenAddress = "localhost";
    builds = {
      #enable = true;
      enableWorker = true;
      images.nixos.unstable.x86_64 =
        let
          systemConfig = { pkgs, ... }: {
            # passwordless ssh server
            services.openssh = {
              enable = true;
              permitRootLogin = "yes";
              extraConfig = "PermitEmptyPasswords yes";
            };

            users = {
              mutableUsers = false;
              # build user
              extraUsers."build" = {
                isNormalUser = true;
                uid = 1000;
                extraGroups = [ "wheel" ];
                password = "";
              };
              users.root.password = "";
            };

            security.sudo.wheelNeedsPassword = false;
            nix.settings.trusted-users = [ "root" "build" ];
            documentation.nixos.enable = false;

            # builds.sr.ht-image-specific network settings
            networking = {
              hostName = "build";
              dhcpcd.enable = false;
              defaultGateway.address = "10.0.2.2";
              usePredictableInterfaceNames = false; # so that we just get eth0 and not some weird id
              interfaces."eth0".ipv4.addresses = [{
                address = "10.0.2.15";
                prefixLength = 25;
              }];
              enableIPv6 = false;
              nameservers = [
                # OpenNIC anycast
                "185.121.177.177"
                "169.239.202.202"
                # Google as a fallback :(
                "8.8.8.8"
              ];
              firewall.allowedTCPPorts = [ 22 ]; # allow ssh
            };

            environment.systemPackages = [
              pkgs.gitMinimal
              #pkgs.mercurial
              pkgs.curl
              pkgs.gnupg
            ];
          };
          qemuConfig = { ... }: {
            imports = [ systemConfig ];
            fileSystems."/".device = "/dev/disk/by-label/nixos";
            boot.initrd.availableKernelModules = [
              "ahci"
              "ehci_pci"
              "sd_mod"
              "usb_storage"
              "usbhid"
              "virtio_balloon"
              "virtio_blk"
              "virtio_pci"
              "virtio_ring"
              "xhci_pci"
            ];
            boot.loader = {
              grub = {
                device = "/dev/vda";
              };
              timeout = 0;
            };
          };
          config = (import (pkgs.path + "/nixos/lib/eval-config.nix") {
            inherit pkgs; modules = [ qemuConfig ];
            system = "x86_64-linux";
          }).config;
        in
        import (pkgs.path + "/nixos/lib/make-disk-image.nix") {
          inherit pkgs lib config;
          diskSize = 16000;
          format = "qcow2-compressed";
          contents = [
            {
              source = pkgs.writeText "gitconfig" ''
                [user]
                  name = builds.sr.ht
                  email = build@sr.ht
              '';
              target = "/home/build/.gitconfig";
              user = "build";
              group = "users";
              mode = "644";
            }
          ];
        };
    };

    #dispatch.enable = true;
    git.enable = true;
    #hub.enable = true;
    meta.enable = true;
    meta.port = 4999;
    #man.enable = true;
    #pages.enable = true;
    #paste.enable = true;
    #todo.enable = true;
    #lists.enable = true;

    postgresql.enable = true;
    postfix.enable = true;
    redis.enable = true;
    nginx.enable = true;
    settings = {
      "sr.ht" = {
        environment = "production";
        global-domain = domain;
        origin = "http://${domain}";
        owner-email = "julm+srht@sourcephile.fr";
        owner-name = "Sourcephile";
        site-blurb = "software forge";
        site-info = "http://${domain}";
        site-name = "Sourcephile";
        # nix shell nixpkgs#sourcehut.coresrht -c srht-keygen network
        network-key = gnupg.secrets."sourcehut/network-key".path;
        # nix shell nixpkgs#sourcehut.coresrht -c srht-keygen service
        service-key = gnupg.secrets."sourcehut/service-key".path;
      };
      objects = {
        s3-upstream = "localhost";
        s3-access-key = "12345";
        s3-secret-key = pkgs.writeText "s3-secret-key" "12345678";
      };
      # nix shell nixpkgs#sourcehut.metasrht -c metasrht-manageuser -t admin -e mymail@gmail.com misuzu
      "builds.sr.ht" = {
        origin = "http://builds.${domain}";
        oauth-client-secret = gnupg.secrets."sourcehut/oauth-client-secret".path;
        oauth-client-id = "299db9f9c2013170";
        allow-free = true;
      };
      "dispatch.sr.ht" = {
        origin = "http://dispatch.${domain}";
        oauth-client-secret = gnupg.secrets."sourcehut/oauth-client-secret".path;
        oauth-client-id = "299db9f9c2013170";
      };
      "pages.sr.ht" = {
        origin = "http://pages.${domain}";
        oauth-client-secret = gnupg.secrets."sourcehut/oauth-client-secret".path;
        oauth-client-id = "299db9f9c2013170";
        s3-bucket = "pagesbuck";
      };
      "paste.sr.ht" = {
        origin = "http://paste.${domain}";
        oauth-client-secret = gnupg.secrets."sourcehut/oauth-client-secret".path;
        oauth-client-id = "299db9f9c2013170";
      };
      "man.sr.ht" = {
        origin = "http://man.${domain}";
        oauth-client-secret = gnupg.secrets."sourcehut/oauth-client-secret".path;
        oauth-client-id = "299db9f9c2013170";
      };
      "meta.sr.ht" = {
        origin = "http://meta.${domain}";
        api-origin = "http://localhost:5099";
      };
      "meta.sr.ht::settings" = {
        onboarding-redirect = "http://meta.${domain}";
        registration = true;
      };
      "meta.sr.ht::api" = {
        # This is a temporary workaround
        #
        internal-ipnet = [ "127.0.0.0/8" "::1/128" "192.168.0.0/16" "10.0.0.0/8" ];
      };
      "todo.sr.ht" = {
        origin = "http://todo.${domain}";
        oauth-client-secret = gnupg.secrets."sourcehut/oauth-client-secret".path;
        oauth-client-id = "299db9f9c2013170";
      };
      "git.sr.ht" = {
        origin = "http://git.${domain}";
        outgoing-domain = "http://git.${domain}";
        oauth-client-secret = gnupg.secrets."sourcehut/oauth-client-secret".path;
        oauth-client-id = "299db9f9c2013170";
        #repos = "/var/lib/git";
      };
      "hub.sr.ht" = {
        origin = "http://hub.${domain}";
        oauth-client-secret = gnupg.secrets."sourcehut/oauth-client-secret".path;
        oauth-client-id = "299db9f9c2013170";
      };
      "lists.sr.ht" = {
        origin = "http://lists.${domain}";
        oauth-client-secret = gnupg.secrets."sourcehut/oauth-client-secret".path;
        oauth-client-id = "299db9f9c2013170";
      };
      "lists.sr.ht::worker" = {
        #sock = "/var/lib/postfix/queue/private/srht-lmtp";
      };
      # nix shell nixpkgs#sourcehut.coresrht -c srht-keygen webhook
      #webhooks.private-key= "U7yd/8mGs/v0O3kId4jpeSghUCa9tqP1fYQwSV8UOqo=";
      webhooks.private-key = gnupg.secrets."sourcehut/webhook-key".path;
      mail = {
        smtp-host = "localhost";
        smtp-port = 25;
        smtp-user = null;
        smtp-password = null;
        smtp-from = "sourcehut@sourcephile.fr";
        error-to = "julm+sourcehut+error@sourcephile.fr";
        error-from = "sourcehut+error@sourcephile.fr";
        pgp-privkey = null;
        pgp-pubkey = null;
        pgp-key-id = null;
      };
    };
  };
  services.nginx.virtualHosts = {
    "builds.${domain}".forceSSL = lib.mkForce false;
    "dispatch.${domain}".forceSSL = lib.mkForce false;
    "git.${domain}".forceSSL = lib.mkForce false;
    "hub.${domain}".forceSSL = lib.mkForce false;
    "lists.${domain}".forceSSL = lib.mkForce false;
    "logs.${domain}".forceSSL = lib.mkForce false;
    "man.${domain}".forceSSL = lib.mkForce false;
    "paste.${domain}".forceSSL = lib.mkForce false;
    "pages.${domain}".forceSSL = lib.mkForce false;
    "todo.${domain}".forceSSL = lib.mkForce false;
    "meta.${domain}" = {
      forceSSL = lib.mkForce false;
      /*
        extraConfig = ''
      access_log /var/log/nginx/${domain}/meta/access.log json;
      error_log /var/log/nginx/${domain}/meta/error.log warn;
        '';
      */
    };
    "${domain}".forceSSL = lib.mkForce false;
  };
  systemd.services.postgresql = {
    /*
      connection_limit=64 \
      encoding=UTF8 \
      lc_collate=fr_FR.UTF-8 \
      lc_type=fr_FR.UTF-8 \
      owner="${sourcehut.git.postgresql.database}" \
      pg_createdb "${sourcehut.git.postgresql.database}" >/dev/null </dev/null

      pg_adduser "${sourcehut.git.postgresql.database}" "${sourcehut.git.postgresql.database}" >/dev/null
      postStart = lib.mkAfter ''
      $PSQL -d "${sourcehut.builds.postgresql.database}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
      GRANT USAGE,CREATE ON schema public TO "${sourcehut.builds.user}";
      EOF
      $PSQL -d "${sourcehut.dispatch.postgresql.database}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
      GRANT USAGE,CREATE ON schema public TO "${sourcehut.dispatch.user}";
      EOF
      $PSQL -d "${sourcehut.git.postgresql.database}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
      GRANT USAGE,CREATE ON schema public TO "${sourcehut.git.user}";
      EOF
      $PSQL -d "${sourcehut.hub.postgresql.database}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
      GRANT USAGE,CREATE ON schema public TO "${sourcehut.hub.user}";
      EOF
      $PSQL -d "${sourcehut.man.postgresql.database}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
      GRANT USAGE,CREATE ON schema public TO "${sourcehut.man.user}";
      EOF
      $PSQL -d "${sourcehut.meta.postgresql.database}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
      GRANT USAGE,CREATE ON schema public TO "${sourcehut.meta.user}";
      GRANT USAGE,CREATE ON schema public TO "${users.sshsrht.name}";
      EOF
      $PSQL -d "${sourcehut.pages.postgresql.database}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
      GRANT USAGE,CREATE ON schema public TO "${sourcehut.pages.user}";
      EOF
      $PSQL -d "${sourcehut.paste.postgresql.database}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
      GRANT USAGE,CREATE ON schema public TO "${sourcehut.paste.user}";
      EOF
      $PSQL -d "${sourcehut.todo.postgresql.database}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
      GRANT USAGE,CREATE ON schema public TO "${sourcehut.todo.user}";
      EOF
      $PSQL -d "${sourcehut.lists.postgresql.database}" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
      GRANT USAGE,CREATE ON schema public TO "${sourcehut.lists.user}";
      EOF
      '';
    */
  };
}