{ config, pkgs, lib, ... }:

let inherit (lib.attrsets) mapAttrs;

in {
  imports = [
    ./services/gitea.nix
    ./services/minecraft.nix
    ./services/monitoring.nix
    ./services/nextcloud.nix
    ./services/webserver.nix
    ./ids.nix
  ];

  nix = {
    # Enable flakes
    package = pkgs.nixFlakes;
    extraOptions = ''
      experimental-features = nix-command flakes
    '';

    # Enable remote builds from tlater
    trustedUsers = [ "@wheel" ];
  };

  boot.kernelParams = [ "highres=off" "nohz=off" ];

  networking = {
    hostName = "tlaternet";

    usePredictableInterfaceNames = false;
    useDHCP = false;
    interfaces.eth0.useDHCP = true;

    firewall.allowedTCPPorts = [ 80 443 2222 2221 25565 ];
  };

  time.timeZone = "Europe/London";

  sops = {
    gnupg = {
      home = "/var/lib/sops";
      sshKeyPaths = [ ];
    };

    defaultSopsFile = "/etc/sops/secrets.yaml";
    validateSopsFiles = false;
  };

  users.users.tlater = {
    isNormalUser = true;
    extraGroups = [ "wheel" ];
    openssh.authorizedKeys.keyFiles = [ ../keys/tlater.pub ];
  };

  services.openssh = {
    enable = true;
    allowSFTP = false;
    passwordAuthentication = false;
    permitRootLogin = "no";
    ports = [ 2222 ];
    startWhenNeeded = true;
  };

  services.nginx = {
    enable = true;
    recommendedTlsSettings = true;
    recommendedOptimisation = true;
    recommendedGzipSettings = true;
    recommendedProxySettings = true;
    clientMaxBodySize = "10G";
    domain = "tlater.net";
    commonHttpConfig = ''
      log_format custom '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referrer" "$http_user_agent" '
                        '$upstream_response_time $request_length $request_time';
      access_log /var/log/nginx/access.log custom;
    '';

    virtualHosts = let
      host = port: extra:
        lib.recursiveUpdate {
          forceSSL = true;
          enableACME = true;
          locations."/".proxyPass = "http://127.0.0.1:${toString port}";
          extraConfig = ''
            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
          '';
        } extra;
      domain = config.services.nginx.domain;
    in {
      "${domain}" = host 3002 { serverAliases = [ "www.${domain}" ]; };
      "gitea.${domain}" = host 3000 { };
      "nextcloud.${domain}" = host 3001 { };
      "grafana.${domain}" = host 3003 { };
    };
  };

  # Allow nginxlog group users to read the nginx log
  users.groups.nginxlog.gid = null;
  systemd.services.nginx.serviceConfig = {
    SupplementaryGroups = [ "nginxlog" ];
    LogsDirectoryMode = lib.mkOverride 99 "0751";
    ExecStartPost = [
      "+${pkgs.coreutils}/bin/chown nginx:nginxlog \${LOGS_DIRECTORY}/access.log \${LOGS_DIRECTORY}/error.log"
    ];
  };

  security.acme = {
    email = "tm@tlater.net";
    acceptTerms = true;
  };

  virtualisation.oci-containers.backend = "podman";

  system.stateVersion = "20.09";
}