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

{ config, depot, lib, pkgs, ... }:
let
  inherit (depot.ops) secrets;
  systemConfig = config;
in {
  imports = [
    ../lib/bvm.nix
    ../lib/pomerium.nix
  ];

  # Networking!
  networking = {
    hostName = "bvm-forgejo";
    hostId = "9cdd4290";
    tempAddresses = "disabled";

    interfaces.enp1s0 = {
      ipv4.addresses = [{ address = "10.100.0.208"; prefixLength = 23; }];
    };
    interfaces.enp2s0 = {
      ipv4.addresses = [{ address = "92.118.28.7"; prefixLength = 24; }];
      ipv6.addresses = [{ address = "2a09:a441::7"; prefixLength = 32; }];
    };
    interfaces.lo = {
      ipv4.addresses = [
        { address = "127.0.0.1"; prefixLength = 8; }
      ];
      ipv6.addresses = [
        { address = "::1"; prefixLength = 128; }
      ];
    };
    defaultGateway = { address = "92.118.28.1"; interface = "enp2s0"; };
    defaultGateway6 = { address = "2a09:a441::1"; interface = "enp2s0"; };

    firewall = {
      allowedTCPPorts = [ 22 80 443 20022 ];
      allowedUDPPorts = [ 443 ];
    };
  };
  my.ip.tailscale = "100.103.26.78";
  my.ip.tailscale6 = "fd7a:115c:a1e0::8d01:1a4e";
  boot.kernel.sysctl = {
    # We have statically-configured v6.
    "net.ipv6.conf.all.accept_ra" = 0;
    "net.ipv6.conf.default.accept_ra" = 0;
  };

  services.openssh.ports = [ 20022 ];
  my.deploy.args = "-p 20022";
  my.rundeck.hostname = "${config.networking.fqdn}:20022";

  users.users.postfix.extraGroups = [ "opendkim" ];

  services.postfix = {
    enable = true;
    domain = "git.lukegb.com";
    hostname = "git.lukegb.com";
    extraConfig = ''
      milter_protocol = 2
      milter_default_action = accept
      smtpd_milters = ${config.services.opendkim.socket}
      non_smtpd_milters = ${config.services.opendkim.socket}
    '';
  };
  services.opendkim = {
    enable = true;
    domains = "csl:git.lukegb.com";
    selector = "bvm-forgejo";
  };
  systemd.services.opendkim.serviceConfig.UMask = lib.mkForce "0007";

  services.pomerium = {
    settings = {
      services = "proxy";
      autocert = true;
      routes = [{
        from = "https://git.lukegb.com";
        to = "http://localhost:3000";
        pass_identity_headers = true;
        remove_request_headers = [
          "X-WebAuth-User"
          "X-WebAuth-Email"
          "X-WebAuth-FullName"
        ];
      }];
    };
  };

  environment.systemPackages = with pkgs; [ forgejo-cli forgejo ];
  services.forgejo = {
    enable = true;
    lfs.enable = true;
    package = pkgs.forgejo;
    secrets = let
      customDir = config.services.forgejo.customDir;
    in {
      storage.MINIO_SECRET_ACCESS_KEY = "${customDir}/conf/s3_secret_key";
    };
    settings = {
      server = {
        DOMAIN = "git.lukegb.com";
        ROOT_URL = "https://git.lukegb.com/";

        START_SSH_SERVER = true;
        BUILTIN_SSH_SERVER_USER = "git";
        SSH_TRUSTED_USER_CA_KEYS = builtins.readFile ../../secrets/client-ca.pub;
        SSH_AUTHORIZED_PRINCIPALS_ALLOW = "username";
      };
      session = {
        COOKIE_SECURE = true;
      };
      storage = {
        STORAGE_TYPE = "minio";
        MINIO_ENDPOINT = "objdump.zxcvbnm.ninja";
        MINIO_BUCKET = "lukegb-forgejo";
        MINIO_LOCATION = "london";
        MINIO_USE_SSL = true;
        MINIO_BUCKET_LOOKUP = "dns";
        MINIO_ACCESS_KEY_ID = "AKIALUKEGBFORGEJO000";
      };
      security = {
        COOKIE_REMEMBER_NAME = "forgejo_remember_me";
        REVERSE_PROXY_AUTHENTICATION_EMAIL = "X-Pomerium-Claim-Email";
      };
      service = {
        DISABLE_REGISTRATION = true;
        ENABLE_REVERSE_PROXY_AUTHENTICATION = true;
        ENABLE_REVERSE_PROXY_EMAIL = true;
      };
      mailer = {
        ENABLED = true;
        PROTOCOL = "smtp";
        SMTP_ADDR = "localhost";
        SMTP_PORT = 25;
        FROM = "lukegb.com Forgejo <forgejo@git.lukegb.com>";
      };
      cron = {
        ENABLED = true;
      };
      log.LEVEL = "Trace";
    };
  };
  systemd.services.forgejo.serviceConfig = {
    PrivateUsers = lib.mkForce false;

    # Allow forgejo to bind port 22.
    AmbientCapabilities = "CAP_NET_BIND_SERVICE";
    CapabilityBoundingSet = lib.mkForce "CAP_NET_BIND_SERVICE";
  };

  system.stateVersion = "24.11";
}