# 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;
in {
  imports =
    [ ../../../third_party/nixpkgs/nixos/modules/installer/scan/not-detected.nix ../lib/client.nix ../lib/whitby-distributed.nix ];

  boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" ];
  boot.kernelModules = lib.mkAfter [ "kvm-intel" ];
  boot.kernelParams = [ "mitigations=off" ];

  fileSystems = let
    zfs = device: {
      device = device;
      fsType = "zfs";
    };
  in {
    "/" = zfs "zboot/safe/root";
    "/nix" = zfs "zboot/local/nix";

    "/home" = zfs "tank/safe/home";
    "/export" = zfs "tank/safe/export";

    "/boot" = {
      device = "/dev/disk/by-uuid/D178-4E19";
      fsType = "vfat";
    };
  };

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

  nix.maxJobs = lib.mkDefault 8;
  powerManagement.cpuFreqGovernor = lib.mkDefault "performance";
  virtualisation = {
    podman.enable = true;
  };

  # Extra packages.
  environment.systemPackages = with pkgs; [
    oven-media-engine
    (depot.nix.pkgs.secretsync.configure {
      workingDir = "/home/lukegb/depot";
      gitlabAccessToken = secrets.deployer.gitlabAccessToken;
      manifestVariable = "SECRETS_MANIFEST";
      variablesToFile = {
        "OPS_SECRETS_DEFAULT_NIX" = "ops/secrets/default.nix";
      };
    })
  ];

  # Networking!
  networking = {
    hostName = "totoro"; # Define your hostname.
    domain = "lukegb.xyz";
    hostId = "676c08c4";
    useDHCP = false;
    interfaces.br-ext.useDHCP = true;
    bridges.br-ext.interfaces = [ "enp0s31f6" ];
  };

  # Virtualisation
  virtualisation.libvirtd = {
    enable = true;
    allowedBridges = [ "virbr0" "br-ext" ];
  };
  users.users.lukegb = {
    packages = with depot.pkgs; [ irssi ];
    extraGroups = lib.mkAfter [ "libvirtd" ];
  };

  # NFS
  services.nfs.server = {
    enable = true;
    exports = ''
      /export 192.168.1.0/24(rw,sync,nohide,no_subtree_check,no_root_squash,wdelay,fsid=0,insecure,crossmnt)
      /export/openshift 192.168.1.0/24(rw,sync,nohide,no_subtree_check,no_root_squash,no_wdelay,insecure,crossmnt)
    '';
  };

  networking.firewall.allowedTCPPorts = [ 111 2049 80 443 6443 22623 ];
  networking.firewall.allowedUDPPorts = [ 111 2049 ];

  # LB
  services.haproxy = {
    enable = true;
    config = ''
      global
        maxconn 50000
        nbthread 4

      defaults
        log global
        mode tcp
        option tcplog
        maxconn 3000
        timeout connect 10s
        timeout client 1m
        timeout server 1m

      frontend k8sapi
        bind 192.168.1.40:6443
        default_backend k8sapi-backend

      backend k8sapi-backend
        balance roundrobin
        mode tcp
        server okd1 192.168.1.41:6443 check
        server okd2 192.168.1.42:6443 check
        server okd3 192.168.1.43:6443 check

      frontend machineconfig
        bind 192.168.1.40:22623
        default_backend machineconfig-backend

      backend machineconfig-backend
        balance roundrobin
        mode tcp
        server okd1 192.168.1.41:22623 check
        server okd2 192.168.1.42:22623 check
        server okd3 192.168.1.43:22623 check

      frontend https
        bind 192.168.1.40:443
        default_backend https-backend

      backend https-backend
        balance roundrobin
        mode tcp
        server okd1 192.168.1.41:443 check
        server okd2 192.168.1.42:443 check
        server okd3 192.168.1.43:443 check

      frontend http
        bind 192.168.1.40:80
        default_backend http-backend

      backend http-backend
        balance roundrobin
        mode tcp
        server okd1 192.168.1.41:80 check
        server okd2 192.168.1.42:80 check
        server okd3 192.168.1.43:80 check
    '';
  };

  # Expose subnet 192.168.1.0/24 via Tailscale.
  boot.kernel.sysctl = {
    "net.ipv4.ip_forward" = 1;
  };

  system.stateVersion = "20.03";
}