{
  lib,
  pkgs,
  config,
  ...
}:
let
  cfg = config.services.forgejo;
  srv = cfg.settings.server;
in
with lib;
{
  options = {
    forgejo = {
      enable = mkEnableOption "enables forgejo";
      port = lib.mkOption {
        type = lib.types.int;
        default = 8003;
        description = "The port that Forgejo is served on.";
      };
      sshPort = lib.mkOption {
        type = lib.types.int;
        default = 3022;
        description = "The ssh port that Forgejo is served on.";
      };
      domain = lib.mkOption {
        type = lib.types.str;
        default = "git.wastring.com";
        description = "The hostname that Forgejo is served on.";
      };
    };
  };
  config = mkMerge [
    (mkIf config.actual.enable {
      services.nginx = {
        virtualHosts.${config.forgejo.domain} = {
          forceSSL = true;
          enableACME = true;
          extraConfig = ''
            client_max_body_size 512M;
          '';
          locations."/".proxyPass = "http://localhost:${toString config.forgejo.port}";
        };
      };

      sops.secrets.smtp_password = { };
      sops.secrets.forgejo-admin-password.owner = "forgejo";
      systemd.services.forgejo.preStart =
        let
          adminCmd = "${lib.getExe cfg.package} admin user";
          pwd = config.sops.secrets.forgejo-admin-password;
          user = "fw";
        in
        ''
          ${adminCmd} create --admin --email "root@localhost" --username ${user} --password "$(tr -d '\n' < ${pwd.path})" || true
          ## uncomment this line to change an admin user which was already created
          # ${adminCmd} change-password --username ${user} --password "$(tr -d '\n' < ${pwd.path})" || true
        '';

      systemd.sockets.forgejo = {
        requiredBy = [ "forgejo.service" ];
        wantedBy = [ "sockets.target" ];

        listenStreams = [
          (toString config.services.forgejo.settings.server.SSH_PORT)
        ];
      };

      sops.secrets.forgejo-runner-token = {};

      # services.gitea-actions-runner = {
      #   package = pkgs.forgejo-actions-runner;
      #   instances.default = {
      #     enable = true;
      #     name = "monolith";
      #     url = "https://git.wastring.com";
      #     # Obtaining the path to the runner token file may differ
      #     # tokenFile should be in format TOKEN=<secret>, since it's EnvironmentFile for systemd
      #     tokenFile = config.sops.secrets.forgejo-runner-token.path;
      #     labels = [
      #       "ubuntu-latest:docker://node:20-bullseye"
      #       # "ubuntu-22.04:docker://node:16-bullseye"
      #       # "ubuntu-20.04:docker://node:16-bullseye"
      #       # "ubuntu-18.04:docker://node:16-buster"
      #       ## optionally provide native execution on the host:
      #       # "native:host"
      #     ];
      #   };
      # };

      services.forgejo = {
        enable = true;
        database.type = "postgres";
        # Enable support for Git Large File Storage
        lfs.enable = true;
        settings = {
          server = {
            DOMAIN = "${config.forgejo.domain}";
            # You need to specify this to remove the port from URLs in the web UI.
            ROOT_URL = "https://${config.forgejo.domain}/";
            HTTP_PORT = config.forgejo.port;
            SSH_PORT = config.forgejo.sshPort;
          };
          # You can temporarily allow registration to create an admin user.
          service.DISABLE_REGISTRATION = true;
          # Add support for actions, based on act: https://github.com/nektos/act
          actions = {
            ENABLED = true;
            DEFAULT_ACTIONS_URL = "github";
          };
          # Sending emails is completely optional
          # You can send a test email from the web UI at:
          # Profile Picture > Site Administration > Configuration >  Mailer Configuration
          mailer = {
            ENABLED = true;
            SMTP_ADDR = "mail.gandi.net";
            FROM = "noreply@${config.forgejo.domain}";
            USER = "fredrik@wastring.com";
          };
        };
        secrets = {
          mailer.PASSWD = config.sops.secrets.smtp_password.path;
        };
      };
    })
  ];

}
