{ config, lib, ... }:
with lib;
let
  cfg = config.nas-apps.gitea;
  settings = import ../settings.nix;
  hostAddress = settings.hostAddress;
  # localAddress = "10.0.4.18";
  # httpPort = 3000;
  # sshPort = 2222;
  rootUrl = "https://gitea.mjallen.dev/";
  # stateDir = "/media/nas/ssd/nix-app-data/gitea";
  dataDir = "/var/lib/gitea";
  secretsDir = "/run/secrets/jallen-nas/gitea";
  mailerPasswordFile = config.sops.secrets."jallen-nas/gitea/mail-key".path;
  metricsTokenFile = config.sops.secrets."jallen-nas/gitea/metrics-key".path;
in
{
  imports = [ ./options.nix ];
  config = mkIf cfg.enable {
    containers.gitea = {
      autoStart = true;
      privateNetwork = true;
      hostAddress = hostAddress;
      localAddress = cfg.localAddress;

      bindMounts = {
        ${dataDir} = {
          hostPath = cfg.dataDir;
          isReadOnly = false;
        };
        secrets = {
          hostPath = secretsDir;
          isReadOnly = true;
          mountPoint = secretsDir;
        };
      };

      config = { lib, ... }:
        {
          services.gitea = {
            enable = true;
            stateDir = dataDir;
            mailerPasswordFile = mailerPasswordFile;
            metricsTokenFile = metricsTokenFile;
            settings = {
              server = {
                DOMAIN = "jallen-nas";
                HTTP_ADDR = "0.0.0.0";
                HTTP_PORT = cfg.httpPort;
                PROTOCOL = "http";
                ROOT_URL = rootUrl;
                START_SSH_SERVER = true;
                SSH_PORT = cfg.sshPort;
              };
              service = {
                REGISTER_EMAIL_CONFIRM = false;
                ENABLE_CAPTCHA = false;
                DISABLE_REGISTRATION = true;
                ENABLE_OPENID_SIGNIN = false;
                ENABLE_LDAP_SIGNIN = false;
                ENABLE_SSH_SIGNIN = true;
                ENABLE_BUILTIN_SSH_SERVER = true;
                ENABLE_REVERSE_PROXY_AUTHENTICATION = true;
              };
            };
          };

          users.users.gitea = {
            extraGroups = [ "keys" ];
          };

          networking = {
            firewall = {
              enable = true;
              allowedTCPPorts = [ cfg.httpPort cfg.sshPort ];
            };
            # Use systemd-resolved inside the container
            # Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
            useHostResolvConf = lib.mkForce false;
          };

          # Create and set permissions for required directories
          system.activationScripts.gitea-dirs = ''
            mkdir -p /var/lib/gitea
            chown -R gitea:gitea /var/lib/gitea
            chmod -R 775 /var/lib/gitea
            mkdir -p /run/secrets/jallen-nas
            chown -R gitea:gitea /run/secrets/jallen-nas
            chmod -R 775 /run/secrets/jallen-nas
          '';

          services.resolved.enable = true;
          system.stateVersion = "23.11";
        };
    };

    services.traefik.dynamicConfigOptions = lib.mkIf cfg.reverseProxy.enable {
      services.gitea.loadBalancer.servers = [
        {
          url = "http://${cfg.localAddress}:${toString cfg.httpPort}";
        }
      ];
      routers.gitea = {
        entryPoints = [ "websecure" ];
        rule = "Host(`${cfg.reverseProxy.host}`)";
        service = "gitea";
        middlewares = cfg.reverseProxy.middlewares;
        tls.certResolver = "letsencrypt";
      };
    };

    networking = {
      nat = {
        forwardPorts = [
          {
            destination = "${cfg.localAddress}:${toString cfg.httpPort}";
            sourcePort = cfg.httpPort;
          }
          {
            destination = "${cfg.localAddress}:${toString cfg.sshPort}";
            sourcePort = cfg.sshPort;
          }
        ];
      };
      firewall = {
        allowedTCPPorts = [ cfg.httpPort cfg.sshPort ];
        allowedUDPPorts = [ cfg.httpPort cfg.sshPort ];
      };
    };
  };
}
