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

let
  streamAudioToOwncastScript = pkgs.writeScriptBin "stream-audio-to-owncast" ''
    #! ${pkgs.runtimeShell} -e

    PATH=${with pkgs; lib.makeBinPath [ coreutils pavucontrol gnome.zenity ffmpeg ]}

    MOVIE="$(zenity --file-selection --title 'Select a video to loop')"
    MOVIE_PREENCODED="/tmp/`basename $MOVIE`.mp4"

    echo
    echo Preencoding the movie. Wait a bit...
    echo

    ffmpeg -i "$MOVIE" -an -s:v 480x320 -c:v libx264 -b:v 600k -f mp4 -y "$MOVIE_PREENCODED"

    echo
    echo "Starting stream. End with <q>"
    echo

    pavucontrol &

    ffmpeg -f pulse -ac 2 -i default -stream_loop -1 -i "$MOVIE_PREENCODED" -c:a aac -c:v copy -f flv rtmp://owncast.serv.zentralwerk.org:1935/live/$(cat ${config.sops.secrets."owncast/authKey".path})
  '';

  streamAudioToOwncast = pkgs.makeDesktopItem rec {
    name = "Stream to Owncast";
    exec = "${streamAudioToOwncastScript}/bin/stream-audio-to-owncast";
    icon = "media-record";
    desktopName = name;
    terminal = true;
  };

in
{
  c3d2 = {
    audioServer.enable = true;
    baremetal = true;
    hq = {
      interface = "eth0";
      statistics.enable = true;
    };
    k-ot.enable = true;
    # TODO: move back to radiobert with the HW
    pi-sensors = if true then [] else [ {
      type = "dht22";
      pin = 17;
      location = "lang";
    } {
      type = "dht22";
      pin = 23;
      location = "kurz";
    } ];
  };

  sops = {
    defaultSopsFile = ./secrets.yaml;
    secrets."owncast/authKey".owner = "k-ot";
  };

  hardware.enableRedistributableFirmware = true;
  powerManagement.cpuFreqGovernor = lib.mkDefault "performance";

  nixpkgs.config.packageOverrides = pkgs: {
    makeModulesClosure = x:
      # prevent kernel install fail due to missing modules
      pkgs.makeModulesClosure (x // { allowMissing = true; });
  };

  boot = {
    # repeat https://github.com/NixOS/nixos-hardware/blob/master/raspberry-pi/4/default.nix#L20
    # to overwrite audio module
    kernelPackages = pkgs.linuxKernel.packages.linux_rpi4;
    loader.raspberryPi = {
      enable = true;
      version = 4;
      firmwareConfig = ''
        gpu_mem=256
        dtparam=audio=on
        disable_overscan=1
        # Display is rotated
        display_hdmi_rotate=1
      '';
    };

    kernelParams = lib.mkForce [
      "snd_bcm2835.enable_headphones=1"
      # don't let sd-image-aarch64.nix setup serial console as it breaks bluetooth.
      "console=tty0"
      # allow GPIO access
      "iomem=relaxed" "strict-devmem=0"
      # booting sometimes fails with an oops in the ethernet driver. reboot after 5s
      "panic=5" "oops=panic"
      # for the patch below
      "compat_uts_machine=armv6l"
    ];

    tmp = {
      useTmpfs = true;
      tmpfsSize = "80%";
    };
  };
  # hardware.raspberry-pi."4" = {
  #   fkms-3d.enable = true;
  # };
  fileSystems."/" = {
    device = "${hostRegistry.nfsroot.ip4}:/var/lib/nfsroot/dacbert";
    fsType = "nfs";
    options = [ "nfsvers=3" "proto=tcp" "nolock" "hard" "async" "rw" ];
  };

  networking = {
    domain = "hq.c3d2.de";
    hostName = "dacbert"; # Define your hostname.
    useDHCP = false;
    interfaces.eth0.useDHCP = true;
  };

  nix = {
    daemonCPUSchedPolicy = "idle";
    daemonIOSchedClass = "idle";
    settings = {
      builders-use-substitutes = true;
      cores = 4;
      extra-platforms = "armv6l-linux";
      max-jobs = 1;
      system-features = [];
      trusted-users = [ "client" ];
    };
  };
  # kernel 32bit personality patch from Ubuntu
  boot.kernelPatches = [
    rec {
      name = "compat_uts_machine";
      patch = pkgs.fetchpatch {
        inherit name;
        url = "https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/jammy/patch/?id=c1da50fa6eddad313360249cadcd4905ac9f82ea";
        sha256 = "sha256-mpq4YLhobWGs+TRKjIjoe5uDiYLVlimqWUCBGFH/zzU=";
      };
    }
  ];

  environment.systemPackages = with pkgs; [
    libraspberrypi
    raspberrypi-eeprom
    vim
    wget
    libva-utils
    mpv
    vlc
    ffmpeg
    yt-dlp
    ncpamixer
    pulseaudio # required for pactl
    chromium
    firefox
    pavucontrol
    glxinfo
    # tracer-game
    bevy_julia
    bevy_mandelbrot
    allcolors
    streamAudioToOwncast
  ];

  security.sudo = {
    enable = true;
    wheelNeedsPassword = false;
  };

  console.keyMap = "de";

  services = {
    # Do not log to flash:
    journald.extraConfig = ''
      Storage=volatile
    '';

    openssh = {
      enable = true;
    };

    xserver = {
      enable = true;
      layout = "de";
      xkbOptions = "eurosign:e";
    };
  };

  services.xserver = {
    desktopManager = {
      gnome.enable = true;
    };

    displayManager = {
      gdm = {
        enable = true;
        wayland = true;
      };
      autoLogin = {
        enable = true;
        user = "k-ot";
      };
      defaultSession = "gnome";
    };
  };

  systemd = {
    services.nix-daemon.serviceConfig = {
      LimitNOFILE = lib.mkForce 8192;
      CPUWeight = 5;
      MemoryHigh = "4G";
      MemoryMax = "6G";
      MemorySwapMax = "0";
  };

    # replaced by gnome-sharing
    # user.services.wayvnc = {
    #   description = "Wayland VNC server";
    #   wantedBy = [ "graphical-session.target" ];
    #   partOf = [ "graphical-session.target" ];
    #   serviceConfig = {
    #     ExecStart = ''
    #       ${pkgs.wayvnc}/bin/wayvnc 0.0.0.0
    #     '';
    #     RestartSec = 3;
    #     Restart = "always";
    #   };
    # };
  };

  system.stateVersion = "21.05"; # Did you read the comment?
}
