#
# Per-system configuration for Trailblazer.
#
# vim: et:ts=2:sw=2:
#
{
  config,
  lib,
  pkgs,
  modulesPath,
  ...
}:
let
  ledOffScript = pkgs.writeScriptBin "ledsoff" ''
        #!${pkgs.bash}/bin/bash
    		openrgb -d 0 -m off -b 0
    		openrgb -d 1 -m off -b 0
    		openrgb -d 2 -m off -b 0
    		openrgb -d 3 -m off -b 0
    		openrgb -d 4 -m off -b 0
        openrgb -d "Corsair Lighting Node Pro" -m direct -z 0 -s 100 -b 0 -c black
        openrgb -d "Corsair Lighting Node Pro" -m direct -z 1 -s 100 -b 0 -c black
  '';

  ledOnScript = pkgs.writeScriptBin "ledson" ''
        #!${pkgs.bash}/bin/bash
    		openrgb -d 0 -m direct -c $1 -b 100
    		openrgb -d 1 -m direct -c $1 -b 100
    		openrgb -d 2 -m direct -c $1 -b 100
    		openrgb -d 3 -m direct -c $1 -b 100
    		openrgb -d 4 -m direct -c $1 -b 100
        openrgb -d "Corsair Lighting Node Pro" -m direct -z 0 -s 100 -b 100 -c $1
        openrgb -d "Corsair Lighting Node Pro" -m direct -z 1 -s 100 -b 100 -c $1
  '';

  commandScript = pkgs.writeScriptBin "trailblazer-command-daemon" ''
    #!${pkgs.xonsh}/bin/xonsh

    print("[I] Trailblazer command service started. Waiting for command.")
    print("----------------------------")

    for verb in !(${pkgs.mosquitto}/bin/mosquitto_sub -h fuuka -t trailblazer/command):
      verb = verb.strip()

      if verb == "lights/off":
        print("[I] Got a 'lights out' request. Making things quiet.")

        # Turn off monitors on each niri session,
        sockets = g`/var/run/user/1000/niri*.sock`
        for socket in sockets:
          print(f"[I] Turning off monitors on niri instance {socket}.")
          !(env NIRI_SOCKET=@(socket) niri msg action power-off-monitors)

        print("[I] Turning off RGB leds.")
        !(${ledOffScript}/bin/ledsoff)

        print("[I] Everything should be... well, not-shiny, captain!")

      if verb == "lights/ledsoff":
        print("[I] Turning off RGB leds.")
        !(${ledOffScript}/bin/ledsoff)

      elif verb == "lights/o":
        print("[I] Setting lights to 'sight colors.")
        !(${ledOnScript}/bin/ledson white)

      elif verb == "lights/t":
        print("[I] Setting lights to tsu colors.")
        !(${ledOnScript}/bin/ledson blue)

      elif verb == "lights/k":
        print("[I] Setting lights to Kaye colors.")
        !(${ledOnScript}/bin/ledson purple)

      elif verb == "lights/w":
        print("[I] Setting lights to Whim colors.")
        !(${ledOnScript}/bin/ledson green)

      elif verb == "lights/s":
        print("[I] Setting lights to Scar colors.")
        !(${ledOnScript}/bin/ledson red)

      elif verb == "lights/e":
        print("[I] Setting lights to Echo colors.")
        !(${ledOnScript}/bin/ledson gray)

      elif verb == "suspend":
        print("[I] Going to sleep, as requested.")
        !(systemctl suspend)

      else:
        print(f"[W] ignoring unknown verb '{verb}'")

      print("----------------------------")
  '';
in
{
  system.stateVersion = "23.11";

  imports = [
    #./ups.nix
    (modulesPath + "/installer/scan/not-detected.nix")
    ../../configs/build-machine-users.nix
  ];

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

  # Networking.
  networking.hostName = "trailblazer";
  networking.networkmanager.enable = true;
  networking.firewall.enable = false;

  # This is a local machine, rather than our typical network-accesed ones.
  # Run an ssh-agent locally.
  programs.ssh.startAgent = true;

  # Let fuse run as our user and still mount with proper perms.
  programs.fuse.userAllowOther = true;

  # Optimize our system for virtualisation.
  boot.kernelPackages = pkgs.linuxPackages_zen;

  # Disallow nouveau so the NVIDIA device is available for VFIO.
  boot.blacklistedKernelModules = [ "nouveau" ];

  # Allow IOMMU members to be sorted into their own groups for passthrough.
  boot.kernelParams = [
    "iommu=on"
    "amd_iommu=on"
    "pcie_acs_override=downstream,multifunction"
  ];

  # Enable fingerprint reader.
  services.fprintd.enable = true;

  #
  # Niri configuration for our monitors.
  #
  home-manager.users.deprekated = {

    programs.niri.settings = {

      # Top monitor.
      outputs."DP-2" = {
        scale = 1.0;
        position = {
          x = 0;
          y = 0;
        };
      };

      # Bottom monitor.
      outputs."DP-3" = {
        scale = 1.0;
        position = {
          x = 0;
          y = 1440;
        };
        mode = {
          width = 3440;
          height = 1440;
          refresh = 144.0;
        };
      };

      # Right, vertical monitor.
      # Note that the y position here makes the monitor not -so- offset.
      outputs."HDMI-A-1" = {
        scale = 1.0;
        position = {
          x = 3440;
          y = 1440;
        };
      };

      input.tablet.map-to-output = "HDMI-A-1";
    };

    # Also position waybar on only one monitor.
    programs.waybar.settings.mainBar.output = "DP-3";
  };

  # Override stylix font sizes.
  stylix.fonts.sizes.desktop = lib.mkForce 16;

  # Use kwin for sddm instead of westin, to account for multi-monitor.
  services.displayManager.sddm.wayland.compositor = "kwin";

  # Use OpenRGB so we can silence our LEDs when appropriate.
  services.hardware.openrgb = {
    enable = true;
    package = pkgs.openrgb-with-all-plugins;
    motherboard = "amd";
  };

  # Provide docker for remote tasks.
  virtualisation.docker.enable = true;
  users.users.deprekated.extraGroups = [ "docker" ];

  #
  # Trailblazer remote service (allows trailblazer things to be controlled via Home Assistant.
  #
  systemd.services.trailblazer-commands = {
    description = "trailblazer command service";

    # Start once we're online.
    wantedBy = [ "default.target" ];
    wants = [ "network-online.target" ];
    after = [ "network-online.target" ];

    script = "${commandScript}/bin/trailblazer-command-daemon";
  };

  #
  # Hardware config.
  #
  boot.initrd.availableKernelModules = [
    "nvme"
    "xhci_pci"
    "ahci"
    "usbhid"
    "usb_storage"
    "sd_mod"
    "dm-raid"
  ];
  boot.initrd.kernelModules = [ ];
  boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
  boot.kernelModules = [
    "kvm-amd"
    "v4l2loopback"
  ];

  fileSystems."/" = {
    device = "/dev/disk/by-label/nix";
    fsType = "xfs";
  };

  fileSystems."/boot" = {
    device = "/dev/disk/by-label/boot";
    fsType = "vfat";
    options = [
      "fmask=0022"
      "dmask=0022"
    ];
  };

  fileSystems."/home" = {
    device = "/dev/disk/by-label/home";
    fsType = "xfs";
  };

  swapDevices = [ ];

  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
  # (the default) this is the recommended approach. When using systemd-networkd it's
  # still possible to use this option, but it's recommended to use it in conjunction
  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
  networking.useDHCP = lib.mkDefault true;
  # networking.interfaces.enp26s0.useDHCP = lib.mkDefault true;
  # networking.interfaces.wlp25s0.useDHCP = lib.mkDefault true;

  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
  hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;

  boot.swraid.enable = true;
  boot.swraid.mdadmConf = ''
    MAILADDR kate@ktemk.in
    ARRAY /dev/md/nixos:0 level=raid0 num-devices=2 metadata=1.2 UUID=325ee7dc:7fcc6062:635e902f:af2552dc
      devices=/dev/nvme0n1p1,/dev/nvme1n1p1
  '';
}
