# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0

{ depot, lib, pkgs, rebuilder, config, ... }:
let
  inherit (depot.ops) secrets;
  machineSecrets = secrets.machineSpecific.clouvider-fra01;

  vhostsConfig = {
    int = rec {
      proxy = _apply (value: { locations."/".proxyPass = value; }) {
        "deluge.int.lukegb.com" = "http://localhost:8112";
        "radarr.int.lukegb.com" = "http://localhost:7878";
        "sonarr.int.lukegb.com" = "http://localhost:8989";
      };
      serve = _apply (value: { root = value; }) {
        "login.int.lukegb.com" = depot.web.login-int;
        "int.lukegb.com" = depot.web.int;
      };
      _apply = f: builtins.mapAttrs (name: value: lib.recursiveUpdate oauth2Host (f value));
    };
  };
  vhosts = vhostsConfig.int.proxy // vhostsConfig.int.serve;
  oauth2Host = {
    locations."/".extraConfig = lib.mkBefore ''
      error_page 401 = /oauth2/start?rd=https://$host$uri;
    '';
    useACMEHost = "int.lukegb.com";
    forceSSL = true;
  };
in {
  imports = [
    ../lib/zfs.nix
    ../lib/bgp.nix
  ];

  boot.initrd.availableKernelModules = [
    "xhci_pci"
    "ahci"
    "nvme"
    "usbhid"
    "usb_storage"
    "sd_mod"
    "sr_mod"
  ];
  boot.kernelModules = [ "kvm-intel" ];

  powerManagement.cpuFreqGovernor = lib.mkDefault "performance";

  fileSystems = let
    zfs = device: {
      device = device;
      fsType = "zfs";
    };
  in {
    "/" = zfs "zfast/local/root";
    "/nix" = zfs "zfast/local/nix";
    "/persist" = zfs "zfast/safe/persist";
    "/home" = zfs "zfast/safe/home";
    "/store" = zfs "zslow/local/store";

    "/boot" = {
      device = "/dev/disk/by-label/ESP";
      fsType = "vfat";
    };
  };

  nix.maxJobs = lib.mkDefault 12;

  # Use systemd-boot.
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  # Networking!
  networking = {
    hostName = "clouvider-fra01";
    domain = "as205479.net";
    hostId = "9e983570";

    nameservers = [
      "2001:4860:4860::8888"
      "2001:4860:4860::8844"
      "8.8.8.8"
      "8.8.4.4"
    ];
    useDHCP = false;
    defaultGateway = {
      address = "193.228.196.56";
      interface = "enp1s0";
    };
    defaultGateway6 = {
      address = "2a0f:93c0:0:22::1";
      interface = "enp1s0";
    };
    interfaces.enp1s0 = {
      useDHCP = false;
      ipv4.addresses = [{ address = "193.228.196.57"; prefixLength = 31; }];
      ipv6.addresses = [{ address = "2a0f:93c0:0:22::2"; prefixLength = 126; }];
    };
    firewall.allowPing = true;
  };

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    rebuilder
  ];

  programs.mtr.enable = true;
  services.openssh.enable = true;

  # Define a user account.
  users.mutableUsers = false;
  users.users = {
    lukegb.extraGroups = [ "wheel" "content" ];
    content = {
      isSystemUser = true;
      extraGroups = [ "content" ];
    };
    plex.extraGroups = [ "content" ];
    deluge.extraGroups = [ "content" ];
    sonarr.extraGroups = [ "deluge" "content" ];
    radarr.extraGroups = [ "deluge" "content" ];
  } // (lib.setAttrByPath [ config.services.nginx.user "extraGroups" ] [ "acme" ]);
  users.groups = {
    content = {};
  };

  services.openssh.hostKeys = [
    {
      path = "/persist/etc/ssh/ssh_host_ed25519_key";
      type = "ed25519";
    }
    {
      path = "/persist/etc/ssh/ssh_host_rsa_key";
      type = "rsa";
      bits = 4096;
    }
  ];

  services.plex = {
    enable = true;
    dataDir = "/store/plex";
    openFirewall = true;
    package = depot.nix.pkgs.plex-pass;
  };

  services.deluge = {
    enable = true;
    declarative = true;
    openFirewall = true;
    dataDir = "/store/deluge";
    config = {
      upnp = false;
      natpmp = false;
      max_active_seeding = 100;
      max_active_downloading = 100;
      max_active_limit = 200;
      move_completed_paths_list = [ "/store/content/Anime" "/store/content/Films" "/store/content/TV" ];
      enabled_plugins = [ "Label" ];
    };
    authFile = machineSecrets.delugeAuthFile;

    web.enable = true;
  };
  services.sonarr = {
    enable = true;
  };
  services.radarr = {
    enable = true;
  };

  security.acme = {
    acceptTerms = true;
    email = "letsencrypt@lukegb.com";
    certs."int.lukegb.com" = {
      domain = "*.int.lukegb.com";
      dnsProvider = "cloudflare";
      credentialsFile = machineSecrets.cloudflareCredentials;
      extraDomainNames = ["int.lukegb.com"];
      postRun = ''
        systemctl reload nginx
      '';
    };
  };

  services.nginx = {
    enable = true;
    virtualHosts = vhosts;
  };
  services.oauth2_proxy = {
    enable = true;
    clientID = "136257844546-6q1mcg4jqc8fcjigutcr47ii8g04qbvt.apps.googleusercontent.com";
    cookie.domain = ".int.lukegb.com";
    email.domains = [ "lukegb.com" ];
    google = {
      adminEmail = "lukegb@lukegb.com";
      serviceAccountJSON = machineSecrets.googleServiceAccount;
    };
    keyFile = machineSecrets.oauth2proxySecrets;
    redirectURL = "https://login.int.lukegb.com/oauth2/callback";
    nginx.virtualHosts = builtins.filter (value: value == "int.lukegb.com" || lib.hasSuffix ".int.lukegb.com" value) (builtins.attrNames vhosts);
    extraConfig = {
      whitelist-domain = ".int.lukegb.com,int.lukegb.com";
    };
  };

  system.stateVersion = "20.03";
}