{ config, pkgs, ... }:

{
  c3d2.deployment.server = "server10";

  environment.systemPackages = [
    # TODO: move into nixos-modules
    (with pkgs.python3.pkgs; buildPythonApplication {
      pname = "hedgedoc-util";
      version = "unstable-2022-04-20";
      format = "other";

      src = pkgs.fetchFromGitLab {
        domain = "git.cccv.de";
        owner = "infra/ansible/roles";
        repo = "hedgedoc";
        rev = "d69cef4bf6c7fe4e67570363659e4c20b0e102af";
        hash = "sha256-dWZtPnQ9ZtS9EEwMA5p9Bhu6zoDQS4fGxVaJ1lPMw/s=";
      };

      # TODO: upstream this?
      patches = [ ./hedgedoc-util-postgres.diff ];

      dontBuild = true;

      propagatedBuildInputs = [
        click
        psycopg2
      ];

      installPhase = let
        wrapper = pkgs.writeShellScriptBin "hedgedoc-util" ''
          cd /var/lib/hedgedoc
          sudo=exec
          if [[ "$USER" != hedgedoc ]]; then
            sudo='exec /run/wrappers/bin/sudo -u hedgedoc --preserve-env'
          fi
          $sudo $(dirname "$0")/.hedgedoc-util "$@"
        '';
      in ''
        mkdir -p $out/bin
        cp files/hedgedoc-util.py $out/bin/.hedgedoc-util
        ln -s ${lib.getExe wrapper} $out/bin/hedgedoc-util
      '';
    })
  ];

  microvm.mem = 1536;

  networking.hostName = "hedgedoc";

  services = {
    backup = {
      enable = true;
      paths = [ "/var/lib/hedgedoc/" ];
    };

    hedgedoc = {
      enable = true;
      ldap.enable = true;
      settings = {
        allowAnonymousEdits = true;
        allowEmailRegister = false;
        allowFreeURL = true;
        allowOrigin = [ "hedgedoc.c3d2.de" ];
        csp = {
          enable = true;
          addDefaults = true;
          upgradeInsecureRequest = "auto";
        };
        db = {
          dialect = "postgres";
          host = "/run/postgresql/";
        };
        defaultPermission = "freely";
        domain = "hedgedoc.c3d2.de";
        email = false; # only allow ldap login
        loglevel = "warn";
        path = "/run/hedgedoc/hedgedoc.sock";
        protocolUseSSL = true;
        sessionSecret = "$sessionSecret";
      };
      environmentFile = config.sops.secrets."hedgedoc".path;
    };

    nginx = {
      enable = true;
      enableReload = true;
      upstreams.hedgedoc.servers."unix:${config.services.hedgedoc.settings.path}" = { };
      virtualHosts = {
        "codimd.c3d2.de" = {
          forceSSL = true;
          enableACME = true;
          locations."/".return = "301 https://hedgedoc.c3d2.de$request_uri";
        };
        "hackmd.c3d2.de" = {
          forceSSL = true;
          enableACME = true;
          locations."/".return = "301 https://hedgedoc.c3d2.de$request_uri";
        };
        "hedgedoc.c3d2.de" = {
          default = true;
          forceSSL = true;
          enableACME = true;
          locations = {
            "^~ /robots\\.txt".return = "200 'User-agent: *\\nDisallow: /'";
            "/".proxyPass = "http://hedgedoc";
          };
        };
      };
    };

    portunus.addToHosts = true;

    postgresql = {
      enable = true;
      ensureDatabases = [
        "hedgedoc"
      ];
      ensureUsers = [ {
        name = "hedgedoc";
        ensurePermissions = {
          "DATABASE \"hedgedoc\"" = "ALL PRIVILEGES";
        };
      }];
      package = pkgs.postgresql_16;
      upgrade.stopServices = [ "hedgedoc" ];
    };
  };

  sops = {
    age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
    defaultSopsFile = ./secrets.yaml;
    secrets = {
      "hedgedoc".owner = config.systemd.services.hedgedoc.serviceConfig.User;
    };
  };

  systemd = {
    services.hedgedoc = {
      preStart = ''
        rm -f ${config.services.hedgedoc.settings.path}
      '';
      serviceConfig.UMask = "0007";
    };
    tmpfiles.rules = [
      "d /run/hedgedoc/ 0770 hedgedoc hedgedoc -"
    ];
  };

  system.stateVersion = "22.11";

  users.users.nginx.extraGroups = [ "hedgedoc" ];
}
