# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

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

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Bootloader.
  boot.loader.grub.enable = true;
  boot.loader.grub.devices = ["nodev"];
  boot.loader.grub.useOSProber = true;
  boot.loader.grub.efiSupport = true;
  boot.initrd.systemd.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;
  boot.loader.grub.timeoutStyle = "hidden";
  services.avahi = {
  enable = true;
  nssmdns4 = true;
  openFirewall = true;
};


boot = {

    plymouth = {
      enable = true;
      theme = "square_hud";
      themePackages = with pkgs; [
        # By default we would install all themes
        (adi1090x-plymouth-themes.override {
          selected_themes = [ "square_hud" ];
        })
      ];
    };

    # Enable "Silent Boot"
    consoleLogLevel = 0;
    initrd.verbose = false;
    kernelPackages = pkgs.linuxPackages_zen;
    /*kernelPatches = [
      {
	name = "dsc";
	patch = ../../patches/vesa-dsc-fixed-bpp.patch;
      }
    ];*/
    kernelParams = [
      "quiet"
      "splash"
      "boot.shell_on_fail"
      "loglevel=3"
      "rd.systemd.show_status=false"
      "rd.udev.log_level=3"
      "udev.log_priority=3"
    ];
    # Hide the OS choice for bootloaders.
    # It's still possible to open the bootloader list by pressing any key
    # It will just not appear on screen unless a key is pressed
    loader.timeout = 0;

  };

  services.udev.extraRules = ''
  ACTION=="add", KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="35bd", ATTRS{idProduct}=="0101", TAG+="uaccess", MODE="0660"
  '';

  boot.extraModulePackages = with config.boot.kernelPackages; [ hid-tmff2 ];

  networking.hostName = "nixos"; # Define your hostname.
  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";

  # Enable networking
  networking.networkmanager.enable = true;
  security.pki.certificateFiles = [ ./certs/beammp.pem ];


  hardware.bluetooth.enable = true;
  hardware.bluetooth.package = pkgs.bluez;

  nixpkgs.config.permittedInsecurePackages = [
    "electron-31.7.7"
    "mbedtls-2.28.10"
  ];

  environment.variables.AMD_VULKAN_ICD = "RADV";

  # Set your time zone.
  time.timeZone = "America/Chicago";
  environment.sessionVariables.NIXOS_OZONE_WL = "1";
  environment.sessionVariables.SDL_GAMECONTROLLERCONFIG = "03002f67c4100000c082000011010000,Shifter,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,platform:Linux";
  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "en_US.UTF-8";
    LC_IDENTIFICATION = "en_US.UTF-8";
    LC_MEASUREMENT = "en_US.UTF-8";
    LC_MONETARY = "en_US.UTF-8";
    LC_NAME = "en_US.UTF-8";
    LC_NUMERIC = "en_US.UTF-8";
    LC_PAPER = "en_US.UTF-8";
    LC_TELEPHONE = "en_US.UTF-8";
    LC_TIME = "en_US.UTF-8";
  };

  # Enable the X11 windowing sytem.
  services.xserver.enable = true;


  # Enable the GNOME Desktop Environment.
  services.desktopManager.plasma6.enable = false;
  services.displayManager.sddm.enable = false;
  services.displayManager.cosmic-greeter.enable = false;
  services.desktopManager.cosmic.enable = true;
  services.desktopManager.gnome.enable = false;
  services.displayManager.gdm.enable = false;
  /*services.displayManager = {
	autoLogin.enable = true;
	autoLogin.user = "joshuaelm";
};*/
  security.pam.services.hyprlock = {};
  programs.noisetorch.enable = true;
  
  services.greetd = {
    enable = true;
    settings = rec {
      initial_session = {
        command = "dbus-launch ${pkgs.hyprland}/bin/Hyprland";
        user = "joshuaelm";
      };
      default_session = initial_session;
    };
  };

  # Steam Deck Gamemode
  programs.steam.gamescopeSession.enable = true;


  # Polkit

  security.polkit.enable = true;
   services.udisks2.enable = true;


  # Configure keymap in X11
  services.xserver = {
    xkb.layout = "us";
    xkb.variant = "";
    excludePackages = [ pkgs.xterm ];
  };


  
  # Enable Swap

  /*swapDevices = [ {
    device = "/var/lib/swapfile";
    size = 16*1024;
  }];*/

  # Enable CUPS to print documents.
  services.printing.enable = true;

  # Enable sound with pipewire.
  services.pulseaudio.enable = false;
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    wireplumber.enable = true;
    # If you want to use JACK applications, uncomment this
    #jack.enable = true;

    # use the example session manager (no others are packaged yet so this is enabled by default,
    # no need to redefine it in your config for now)
    #media-session.enable = true;
    wireplumber.configPackages = [
      (pkgs.writeTextDir "share/wireplumber/wireplumber.conf.d/alsa.conf" ''
        monitor.alsa.rules = [
          {
            matches = [
              {
                device.name = "~alsa_card.*"
              }
            ]
            actions = {
              update-props = {
                # Device settings
                api.alsa.use-acp = true
              }
            }
          }
          {
            matches = [
              {
                node.name = "~alsa_input.*"
              }
              {
                node.name = "~alsa_output.*"
              }
            ]
            actions = {
            # Node settings
              update-props = {
                session.suspend-timeout-seconds = 0
              }
            }
          }
        ]
      '')
    ];

  };
  services.pulseaudio.configFile = pkgs.runCommand "default.pa" {} ''
  sed 's/module-udev-detect$/module-udev-detect tsched=0/' \
    ${pkgs.pulseaudio}/etc/pulse/default.pa > $out
'';
  environment.etc."wireplumber/main.lua.d/90-suspend-timeout.lua" = {
    text = ''
      session.suspend-timeout-seconds = 0
      '';
    };

  services.pipewire.extraConfig.pipewire-pulse."92-low-latency" = {
  context.modules = [
    {
      name = "libpipewire-module-protocol-pulse";
      args = {
        pulse.min.req = "32/48000";
        pulse.default.req = "32/48000";
        pulse.max.req = "32/48000";
        pulse.min.quantum = "32/48000";
        pulse.max.quantum = "32/48000";
      };
    }
  ];
  stream.properties = {
    node.latency = "32/48000";
    resample.quality = 1;
  };
};
hardware.pulseaudio.extraConfig = ''
  .nofail
  unload-module module-suspend-on-idle
  .fail
'';


  # Enable touchpad support (enabled default in most desktopManager).
  # services.xserver.libinput.enable = true;

  # Define a user account. Don't forget to set a password with ‘passwd’.
  programs.adb.enable = true;
  users.users.joshuaelm = {
    isNormalUser = true;
    description = "Joshua Elmasri";
    extraGroups = [ "networkmanager" "input" "wheel" "adbusers" ];
    packages = with pkgs; [
    #  thunderbird
    ];
    shell = pkgs.fish;
  };

  programs.fish.enable = true;

  nix.optimise.automatic = true;

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;

  # Configure drives

  fileSystems."/mnt/Games" = {
    device = "/dev/nvme0n1p1";
    fsType = "btrfs";
    options = [
      "users"
      "nofail"
      "x-gvfs-show"
      "exec"
    ];
  };


  /*fileSystems."/mnt/More-Games" = {
    device = "/dev/sdb1";
    fsType = "btrfs";
    options = [
      "users"
      "nofail"
      "x-gvfs-show"
      "exec"
    ];
  };*/






  # Fonts
  fonts.packages = with pkgs; [
    fira-code
    fira-code-symbols
    roboto
    nerd-fonts.fira-code
    nerd-fonts.jetbrains-mono
  ];


  services.moltengamepad.enable = true;

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    (pkgs.buildFHSEnv {
      name = "fhs";
      targetPkgs = pkgs: with pkgs; [
        alsa-lib atk cairo cups curl dbus expat file fish fontconfig freetype
        fuse glib gtk3 libGL libnotify libxml2 libxslt netcat nspr nss openjdk8
        openssl.dev cava pango appimage-run pkg-config strace udev vulkan-loader watch wget which
        xorg.libX11 icu xorg.libxcb xorg.libXcomposite xorg.libXcursor
        xorg.libXdamage xorg.libXext xorg.libXfixes xorg.libXi xorg.libXrandr
        xorg.libXrender xorg.libXScrnSaver openssl xorg.libxshmfence xorg.libXtst
        xorg.xcbutilkeysyms zlib fontconfig.lib SDL2 libGL libuuid xorg.libXft
      ];
      profile = ''export FHS=1'';
      runScript = "fish";
    })
    git
    bibata-cursors
    killall
    usbutils
    mangohud
    # cemu broken with latest update
    oterm
    wget
    wlx-overlay-s
    labymod-launcher
    unzip
    winetricks
    cowsay
    pfetch
    ryubing
    gomatrix
    python3
    pavucontrol
    bluebubbles
    xfce.thunar
    parallel-launcher
    wiremix
    termsonic
    steamtinkerlaunch
    kdePackages.kdenlive
    wineWowPackages.wayland
    blueman
    lapce
    prismlauncher
    protonup-qt
    openjdk23
    heroic
    protontricks
    gamescope
    playerctl
    wine
    #alvr
    libreoffice
    neovide
    flatpak
  ];

  # VirtualBox

  virtualisation.virtualbox.host.enable = false;
  users.extraGroups.vboxusers.members = [ "user-with-access-to-virtualbox" ];

  services.flatpak.enable = true;


  services.sunshine = {
    enable = true;
    autoStart = false;
    capSysAdmin = true;
    openFirewall = true;
    
  };
  # Enable Steam
  programs.steam = {
    enable = true;
    remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
    dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
  };
  hardware.steam-hardware.enable=true;
  services.monado = {
    enable = true;
    defaultRuntime = true; # Register as default OpenXR runtime
  };
  systemd.user.services.monado.environment = {
    STEAMVR_LH_ENABLE = "1";
    XRT_COMPOSITOR_COMPUTE = "1";
    WMR_HANDTRACKING = "0";
  };


  nixpkgs.config.packageOverrides = pkgs: {
    steam = pkgs.steam.override {
      extraLibraries = pkgs: [ pkgs.xorg.libxcb ];
      extraPkgs = pkgs: with pkgs; [
        xorg.libXcursor
	xorg.libXi
	xorg.libXinerama
	xorg.libXScrnSaver
	libpng
	libpulseaudio
	libvorbis
	stdenv.cc.cc.lib
	libkrb5
	keyutils
      ];
    };
  };

  programs.gamescope = {
    enable = true;
    capSysNice = true;
  };

  programs.nix-ld.enable = true;

  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
   services.openssh.enable = true;
   services.openssh.allowSFTP = true;
   services.openssh.settings.PasswordAuthentication = true;

  # Open ports in the firewall.
   networking.firewall.allowedTCPPorts = [ 7860 3042 3246 9943 9944 7801 11434 47990 48010 5001 ];
   networking.firewall.allowedUDPPorts = [ 7860 9943 9944 3042 47990 3246 11434 7801 4800 48010 ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "23.11"; # Did you read the comment?
  # Enable lakes
 nix = {
  extraOptions = ''
    experimental-features = nix-command flakes
  '';
};

}
