{ depot, lib, pkgs, rebuilder, ... }:
{ config, ... }:
let
  inherit (depot.ops) secrets;
  myPhp = pkgs.php.withExtensions ({ enabled, all }: enabled ++ [ all.apcu all.mailparse ]);
in {
  imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ];
  boot.kernelModules = [ "tcp_bbr" ];
  boot.kernel.sysctl = {
    "net.ipv6.conf.default.accept_ra" = 1;
    "net.ipv6.conf.all.accept_ra" = 1;
  };

  fileSystems = {
    "/" = {
      device = "/dev/vda1";
      fsType = "ext4";
    };
  };

  nix.maxJobs = lib.mkDefault 2;
  hardware.enableRedistributableFirmware = true;

  nix.nixPath = [ "depot=/home/lukegb/depot/" "nixpkgs=/home/lukegb/depot/third_party/nixpkgs/" ];

  # Use GRUB2.
  boot.loader.grub.enable = true;
  boot.loader.grub.version = 2;
  boot.loader.grub.device = "/dev/vda";

  # Networking!
  networking = {
    hostName = "marukuru"; # Define your hostname.
    domain = "lukegb.xyz";
    nameservers = ["2001:4860:4860::8888" "8.8.8.8"];
    useDHCP = false;
    defaultGateway = {
      address = "103.105.48.1"; interface = "eth0";
    };
    dhcpcd.enable = false;
    usePredictableInterfaceNames = true;
    interfaces = {
      eth0 = {
        ipv4.addresses = [
          { address="103.105.48.15"; prefixLength=24; }
        ];
        ipv6.addresses = [
          { address="2402:28c0:4:104e::1"; prefixLength=64; }
        ];
      };
    };
  };
  services.udev.extraRules = ''
    ATTR{address}=="52:54:00:84:e2:2a", NAME="eth0"
  '';

  # Select internationalisation properties.
  i18n.defaultLocale = "en_GB.UTF-8";
  console.keyMap = "us";

  # Set your time zone.
  time.timeZone = "Etc/UTC";

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    vim
    mercurial
    gitAndTools.gitFull
    nodejs
    rxvt_unicode.terminfo
    python37Packages.pygments
    rebuilder
    myPhp
  ];
  environment.etc."php.d/cache.ini".text = ''
    zend_extension=${pkgs.php}/lib/php/extensions/opcache.so

    opcache.validate_timestamps=0
    opcache.enable_cli=1
  '';
  environment.etc."ssh/phabricator-ssh-hook" = {
    text = ''
      #!${pkgs.stdenv.shell}
      VCSUSER="vcs"
      ROOT="/srv/http/phab.lukegb.com/phabricator"
      PATH="${pkgs.php}/bin:$PATH"

      if [ "$1" != "$VCSUSER" ];
      then
        exit 1
      fi

      exec "$ROOT/bin/ssh-auth" $@
    '';
    mode = "0555";
    user = "root";
    group = "root";
  };
  environment.etc."phabricator-php" = {
    text = ''
      #!${pkgs.stdenv.shell}
      export PATH="${pkgs.php}/bin:$PATH"
      exec "${pkgs.php}/bin/php" $@
    '';
    mode = "0555";
    user = "root";
    group = "root";
  };
  environment.etc."ssh/sshd_config.phabricator".text = ''
    AuthorizedKeysCommand /etc/ssh/phabricator-ssh-hook
    AuthorizedKeysCommandUser vcs
    AllowUsers vcs anonvcs

    KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
    Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
    MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com

    Port 22
    Protocol 2
    PermitRootLogin no
    AllowAgentForwarding no
    AllowTcpForwarding no
    PrintMotd no
    PrintLastLog no
    PasswordAuthentication no
    ChallengeResponseAuthentication no
    AuthorizedKeysFile none

    Match User anonvcs
      ForceCommand /srv/http/phab.lukegb.com/phabricator/bin/ssh-exec --phabricator-ssh-user anonymous --phabricator-ssh-key 1
      PasswordAuthentication yes
      PermitEmptyPasswords yes
      AuthenticationMethods none password
      PermitListen none
      PermitOpen none
      X11Forwarding no
      PermitTTY no
      PermitTunnel no
      AllowAgentForwarding no
      AllowTcpForwarding no
      AllowStreamLocalForwarding no
  '';
  systemd.services."sshd-phabricator" = {
    description = "SSH Daemon for Phabricator";
    stopIfChanged = false;
    wantedBy = ["multi-user.target"];
    path = [ config.programs.ssh.package ];
    environment.LD_LIBRARY_PATH = config.system.nssModules.path;
    restartTriggers = [
      config.environment.etc."ssh/sshd_config".text
    ];
    serviceConfig = {
      ExecStart = "${config.programs.ssh.package}/bin/sshd -f /etc/ssh/sshd_config.phabricator";
      KillMode = "process";
      Restart = "always";
      Type = "simple";
    };
  };

  programs.mtr.enable = true;
  services.openssh.enable = true;
  services.openssh.ports = [ 20022 ];

  networking.firewall = {
    allowedTCPPorts = [ 22 80 443 20022 ];
    # allowedUDPPorts = [];
    allowPing = true;
  };

  # Define a user account.
  users.mutableUsers = false;
  users.groups = {
    phabricator = {};
  };
  users.users = {
    root.hashedPassword = secrets.passwordHashes.root;
    lukegb = {
      isNormalUser = true;
      uid = 1000;
      extraGroups = [ "wheel" ];
      hashedPassword = secrets.passwordHashes.root;
    };
    phabricator = {
      isSystemUser = true;
      home = "/srv/http/phab.lukegb.com";
      group = "phabricator";
    };
    postfix = {
      extraGroups = [ "opendkim" ];
    };
    vcs = {
      isSystemUser = true;
      hashedPassword = "NP";
      shell = "/bin/sh";
      group = "phabricator";
    };
    anonvcs = {
      isSystemUser = true;
      hashedPassword = "";
      shell = "/bin/sh";
      group = "phabricator";
    };
  };
  security.sudo.extraRules = [{
    users = [ "vcs" "anonvcs" ];
    runAs = "phabricator";
    commands = map (command: { inherit command; options = [ "NOPASSWD" "SETENV" ]; }) [
      "${pkgs.git}/bin/git"
      "${pkgs.git}/bin/git-upload-pack"
      "${pkgs.git}/bin/git-receive-pack"
      "${pkgs.mercurial}/bin/hg"
    ];
  }];

  services.nginx = {
    enable = true;
    virtualHosts."phab.lukegb.com" = {
      serverAliases = [ "phabusercontent.zxcvbnm.ninja" ];
      forceSSL = true;
      enableACME = true;
      locations."/" = {
        root = "/srv/http/phab.lukegb.com/phabricator/webroot";
        extraConfig = ''
          client_max_body_size 512M;

          location / {
            index index.php;
            rewrite ^/(.*)$ /index.php?__path__=/$1 last;
          }
          location /index.php {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass            unix:${config.services.phpfpm.pools.phabricator.socket};
            fastcgi_index           index.php;

            #required if PHP was built with --enable-force-cgi-redirect
            fastcgi_param  REDIRECT_STATUS    200;

            #variables to make the $_SERVER populate in PHP
            fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
            fastcgi_param  QUERY_STRING       $query_string;
            fastcgi_param  REQUEST_METHOD     $request_method;
            fastcgi_param  CONTENT_TYPE       $content_type;
            fastcgi_param  CONTENT_LENGTH     $content_length;

            fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;

            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
            fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

            fastcgi_param  REMOTE_ADDR        $remote_addr;
            fastcgi_param  HTTPS              on;
          }
        '';
      };
    };
    virtualHosts."phab-ws.lukegb.com" = {
      forceSSL = true;
      enableACME = true;
      locations."/" = {
        proxyPass = "http://127.0.0.1:22280/";
        proxyWebsockets = true;
      };
    };
  };

  services.phpfpm.phpOptions = ''
    zend_extension=${pkgs.php}/lib/php/extensions/opcache.so

    opcache.validate_timestamps=0
    opcache.enable_cli=1
  '';
  services.phpfpm.pools.phabricator = {
    user = "phabricator";
    phpPackage = myPhp;
    settings = {
      "listen.owner" = config.services.nginx.user;
      "pm" = "dynamic";
      "pm.max_children" = 32;
      "pm.max_requests" = 500;
      "pm.start_servers" = 2;
      "pm.min_spare_servers" = 2;
      "pm.max_spare_servers" = 5;
      "php_admin_value[error_log]" = "syslog";
      "php_admin_flag[log_errors]" = true;
      "php_admin_value[date.timezone]" = "Europe/London";
      "php_admin_value[post_max_size]" = "512M";
      "php_admin_value[memory_limit]" = "-1";
      "php_admin_value[max_input_vars]" = "999999999";
      "php_admin_value[upload_max_filesize]" = "512M";
      "catch_workers_output" = true;
    };
    phpEnv."PATH" = lib.makeBinPath [ pkgs.php ];
  };

  services.mysql = {
    enable = true;
    package = pkgs.mariadb;
    settings.mysqld = {
      max_allowed_packet = "128M";
      sql_mode = "STRICT_ALL_TABLES";
      innodb_buffer_pool_size = "1600M";
      local_infile = "0";
    };
  };

  services.postfix = {
    enable = true;
    domain = "phab.lukegb.com";
    hostname = "phab.lukegb.com";
    extraAliases = ''
      phabricator: "|${pkgs.php}/bin/php /srv/http/phab.lukegb.com/phabricator/scripts/mail/mail_handler.php"
    '';
    virtual = ''
      @phab.lukegb.com phabricator@localhost
    '';
    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:phab.lukegb.com";
    selector = "marukuru";
  };

  security.acme = {
    acceptTerms = true;
    email = "letsencrypt@lukegb.com";
  };

  boot.kernel.sysctl."net.ipv4.tcp_congestion_control" = "bbr";
  boot.kernel.sysctl."net.core.default_qdisc" = "fq_codel";

  system.stateVersion = "20.03";
}