# 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').

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

let
  /*
   * pkg: package - nixpkgs package
   * exe: string - executable (under bin) in pkgs
   * wrapperArgs: string[] - arguments to pass to the wrapper
   */
  mkWrappedExecutable = {pkg, exe ? pkg.meta.mainProgram, wrapperArgs}: let inherit (pkgs) lib makeWrapper; in lib.hiPrio (
      pkgs.stdenv.mkDerivation {
      inherit wrapperArgs;
      name = "${pkg.name}-wrap-${exe}";
      nativeBuildInputs = [ makeWrapper ];
      phases = ["installPhase"];
      installPhase = ''
        mkdir -p $out/bin
        makeWrapper ${pkg}/bin/${exe} $out/bin/${exe} $wrapperArgs
      '';
    }
  );

  # bool -> nixpkgs[]
  wrappedNixExecutables = inEnvironment: assert builtins.isBool inEnvironment; [
    (mkWrappedExecutable {pkg = pkgs.nix; exe = "nix-build"; wrapperArgs = ["--add-flags" "\"--log-format\"" "--add-flags" "bar${lib.optionalString inEnvironment "-with-logs"}"];})
    (mkWrappedExecutable {pkg = pkgs.nix; exe = "nix-shell"; wrapperArgs = ["--add-flags" "\"--log-format\"" "--add-flags" "bar"];})
  ];
  wrappedNixosExecutables = [
    (mkWrappedExecutable {pkg = pkgs.nixos-rebuild; wrapperArgs = ["--add-flags" "\"--log-format\"" "--add-flags" "bar"];})
  ];
  wrappedNix = (pkgs.buildEnv {
    name = "wrappedNix-${pkgs.nix.version}";
    paths = [ pkgs.nix ] ++ wrappedNixExecutables false;
  }).overrideAttrs {
    version = pkgs.nix.version;
  };
in
{
  # kernel
  boot.kernelPackages = pkgs.linuxPackages_latest;

  # Enable networking
  networking.networkmanager.enable = true;

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;
  nix = {
    package = wrappedNix;
    channel.enable = false;
    settings.nix-path = [
      "nixpkgs=${pkgs.selfExpr { useConfig = false; }}"
      "systemNixpkgs=${pkgs.selfExpr { useConfig = true; name = "systemNixpkgs-self"; }}"
      # don't garbage collect the nixpkgs input
      "inputsNixpkgs=${inputs.nixpkgs}"
    ];
  };

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    wget
    ffmpeg
    yt-dlp
    htop
    btop
    fastfetch
    smartmontools
    ddrescue
  ] ++ wrappedNixExecutables true
    ++ wrappedNixosExecutables;

  programs.git.enable = true;
  programs.git.config = {
    init.defaultBranch = "main";
    merge.conflictstyle = "diff3";
    rerere.enabled = true;
  };

  # Enable fail2ban because of the OpenSSH server
  services.fail2ban = {
    enable = true;
    maxretry = 10;
    bantime = "7d";
  };

  # Enable the OpenSSH daemon.
  services.openssh = {
    enable = true;
    ports = [
      22
      8022
    ];
  };
}