# 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
  inherit (pkgs) mkWrappedExecutable;

  # 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;
    passthru.meta = pkgs.nix.meta;
  };
in
{
  imports = [
    ./module-overrides.nix
  ];

  # 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.experimental-features = [
      "no-url-literals"
    ];
    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 = {
    commit.verbose = true;
    init.defaultBranch = "main";
    merge.conflictstyle = "diff3";
    rerere.enabled = true;
  };

  # Use nix-index for command-not-found handler
  programs.command-not-found.enable = false;
  programs.nix-index = {
    package = pkgs.nix-index.override {
      nix-index-unwrapped = pkgs.nix-index-unwrapped.overrideAttrs (oldAttrs: {
        patches = oldAttrs.patches or [] ++ [
          ../pkgs/by-name/ni/nix-index/cnfOutput.patch
        ];
      });

    };
    enable = true;
    enableBashIntegration = 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
    ];
  };
}