{
  config,
  lib,
  pkgs,
  ...
}: let
  cfg = config.vhack.git-server;

  cgitCss = import ./css.nix {
    inherit pkgs;
    cgitPkg =
      config.services.cgit."${cfg.domain}".package;
  };
in {
  options.vhack.git-server = {
    enable = lib.mkEnableOption ''
      a lightweight git-server, realised with cgit and gitolite.
    '';

    domain = lib.mkOption {
      type = lib.types.str;
      default = "git.vhack.eu";
      description = ''
        The domain this git instance will run under.
      '';
    };

    gitolite = {
      adminPubkey = lib.mkOption {
        description = ''
          The initial key to use for gitolite. This will only be used for the initial
          clone of the `gitolite-admin` repository.
        '';
        type = lib.types.str;
        default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAe4o1PM6VasT3KZNl5NYvgkkBrPOg36dqsywd10FztS openpgp:0x21D20D6A";
      };
    };
  };

  config = lib.mkIf cfg.enable {
    programs.git = {
      enable = true;
      config = {
        init = {
          defaultBranch = "main";
        };
      };
    };

    # Needed for the nginx proxy and the virtual host
    vhack = {
      nginx.enable = true;
      persist.directories = [
        {
          directory = "/var/lib/gitolite";
          user = "git";
          group = "git";
          mode = "0755";
        }
      ];
    };

    services = {
      gitolite = {
        inherit (cfg.gitolite) adminPubkey;
        enable = true;
        dataDir = "/var/lib/gitolite";
        user = "git";
        group = "git";
        extraGitoliteRc = ''
          $RC{UMASK} = 0027; # Enable group access, important for cgit.

          # Enable modifing git variables (for cgit.owner and such things)
          # These must be enable in the gitolite-admin repo (option user-configs = ...)
          push( @{$RC{ENABLE}}, 'config' );
          push( @{$RC{ENABLE}}, 'git-config' );

          push( @{$RC{ENABLE}}, 'expand-deny-messages' );
          push( @{$RC{ENABLE}}, 'Motd' );

          push( @{$RC{ENABLE}}, 'cgit' );
        '';
      };

      cgit."${cfg.domain}" = {
        enable = true;
        package = pkgs.cgit-pink;
        scanPath = "${config.services.gitolite.dataDir}/repositories";
        user = "git";
        group = "git";
        settings = {
          branch-sort = "age";

          # Allow users to download a repo checkout with these compression formats
          snapshots = ["tar.gz" "zip"];
          # The template used to generate the clone url for https clone.
          clone-url = [
            "https://${cfg.domain}/$CGIT_REPO_URL"
            "ssh://git@${cfg.domain}/$CGIT_REPO_URL"
          ];
          enable-http-clone = true;

          # TODO: We might want to add an logo and readme here <2024-07-31>
          # logo = "<url>";
          # root-readme = "/some/readme/file"
          root-desc = "The cgit instance of ${cfg.domain}!";
          root-title = "${
            lib.strings.toUpper (builtins.substring 0 1 cfg.domain) + builtins.substring 1 (builtins.stringLength cfg.domain) cfg.domain
          } cgit instace";

          # Set the default maximum statistics period. Valid values are "week",
          # "month", "quarter" and "year".
          max-stats = "week";

          readme = [
            ":README.md"
            ":readme.md"
            ":README.mkd"
            ":readme.mkd"
            ":README.rst"
            ":readme.rst"
            ":README.html"
            ":readme.html"
            ":README.htm"
            ":readme.htm"
            ":README.txt"
            ":readme.txt"
            ":README"
            ":readme"
            ":INSTALL.md"
            ":install.md"
            ":INSTALL.mkd"
            ":install.mkd"
            ":INSTALL.rst"
            ":install.rst"
            ":INSTALL.html"
            ":install.html"
            ":INSTALL.htm"
            ":install.htm"
            ":INSTALL.txt"
            ":install.txt"
            ":INSTALL"
            ":install"
          ];

          enable-blame = true;
          enable-commit-graph = true;
          enable-subject-links = true;
          enable-follow-links = true;
          enable-index-links = true;
          enable-index-owner = true;

          # NOTE: This allows cgit to take configuration from the bare git repositories:
          # All `repo.<key>` can be set by setting `cgit.<key>` in the git config. E.g.:
          # setting the owner (i.e. `repo.owner`) would be done by setting the
          # `cgit.owner` config. All repo options are outline in the cgitrc (5) man page.
          enable-git-config = true;

          # Remove the `.git` suffix from scanned repositories (this must be set _before_ `scan-path`)
          remove-suffix = true;

          css = "/custom_cgit.css";

          # This is a number of path elements to treat as section.
          # `-1` means that we treat the last element as name, all others as sections
          section-from-path = -1;

          project-list = "${config.services.gitolite.dataDir}/projects.list";

          # TODO:  We might want to use the kernel.org `libravatar.lua` email-filter <2024-07-31>
          source-filter = "${config.services.cgit."${cfg.domain}".package}/lib/cgit/filters/syntax-highlighting.py";
          about-filter = "${config.services.cgit."${cfg.domain}".package}/lib/cgit/filters/about-formatting.sh";
        };
      };

      nginx.virtualHosts."${cfg.domain}" = {
        enableACME = true;
        forceSSL = true;

        locations = {
          "= /custom_cgit.css" = {
            alias = cgitCss.outPath;
          };
        };
      };
    };
  };
}