# 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,
  zremap,
  system,
  nvim,
  ...
}: {
  imports = [];

  system.stateVersion = "23.05";
  system.autoUpgrade.enable = false;

  sops.age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"];
  sops.secrets."peerix/private" = {
    sopsFile = ./secrets/peerix.yaml;
    mode = "0400";
    owner = config.users.users.nobody.name;
    group = config.users.users.nobody.group;
  };

  sops.secrets."wg_privkey" = {
    sopsFile = ./secrets/wg_privkey.yaml;
  };

  sops.secrets."wg_preshared/mediabox" = {
    sopsFile = ../common/secrets/wg_preshared.yaml;
  };

  nix = {
    optimise.automatic = true;
    gc.automatic = true;
    gc.options = "--delete-older-than 7d";
    package = pkgs.nixVersions.latest;
    settings = {
      experimental-features = ["nix-command" "flakes"];
    };
  };

  boot = {
    initrd = {
      compressor = "zstd";
      availableKernelModules = ["e1000e"];
      network = {
        enable = true;
        udhcpc.enable = true;
        ssh = {
          enable = true;
          hostKeys = [/etc/ssh_dummy_ed25519_key];
          authorizedKeys = [(builtins.readFile ../nixy/ssh_pubkey)];
        };
      };
    };

    kernelModules = ["acpi_call"];
    kernelPackages = pkgs.linuxPackages_latest;
    kernelParams = ["msr.allow_writes=on"];
    kernel.sysctl = {
      "net.core.default_qdisc" = "fq";
      "net.ipv4.tcp_congestion_control" = "bbr";
    };
    loader.systemd-boot = {
      editor = false;
      enable = true;
      memtest86.enable = true;
    };
    readOnlyNixStore = true;
    supportedFilesystems = ["btrfs"];
    tmp.useTmpfs = true;
    tmp.tmpfsSize = "80%";
  };

  security = {
    rtkit.enable = true;
    acme = {
      acceptTerms = true;
      defaults.email = "aasmir@gmx.com";
    };
  };

  powerManagement = {
    enable = true;
    cpuFreqGovernor = "ondemand";
  };

  networking = {
    firewall = {
      enable = true;
      allowedTCPPorts = [80 443 51820];
    };

    hostName = "mediabox";
    interfaces.enp0s25.useDHCP = true;
    interfaces.wlp3s0.useDHCP = false;
    useDHCP = false;
    wireless.enable = false;
    wireless.interfaces = ["wlp3s0"];
    nameservers = ["127.0.0.1" "::1"];
    dhcpcd.extraConfig = "nohook resolv.conf";
    networkmanager.dns = "none";
    extraHosts = ''
      192.168.1.173 nixy.lan
      192.168.88.171 jellyfin.mediabox.lan
      192.168.88.171 mediabox.lan
      192.168.88.171 qbittorrent.mediabox.lan
      192.168.88.1   router.lan
      192.168.88.231 workstation.lan
    '';

    wireguard.interfaces = {
      wg0 = {
        ips = ["10.100.0.5/24"];
        privateKeyFile = config.sops.secrets."wg_privkey".path;
        peers = [
          {
            publicKey = builtins.readFile ../magpie/wg_pubkey;
            presharedKeyFile = config.sops.secrets."wg_preshared/mediabox".path;
            allowedIPs = ["10.100.0.0/24"];
            endpoint = "5.75.229.224:51820";
            persistentKeepalive = 25;
          }
        ];
      };
    };
  };

  time.timeZone = "Europe/Sarajevo";

  nixpkgs.config.allowUnfree = true;
  nixpkgs.overlays = [nvim.overlays.${system}.overlay];
  environment = {
    homeBinInPath = true;
    variables = {
      PATH = "$HOME/.cargo/bin";
    };
  };

  programs.gnupg.agent = {
    enable = true;
    enableSSHSupport = true;
  };
  programs.zsh.enable = true;
  programs.light.enable = true;
  programs.firejail.enable = true;
  programs.adb.enable = false;
  programs.wireshark.enable = true;
  programs.sway.enable = true;

  # List services that you want to enable:
  systemd = {
    services = {
      "macchanger-wireless" = {
        after = ["sys-subsystem-net-devices-wlp3s0.device"];
        before = ["network-pre.target"];
        bindsTo = ["sys-subsystem-net-devices-wlp3s0.device"];
        description = "Changes MAC of my wireless interface for privacy reasons";
        stopIfChanged = false;
        wantedBy = ["multi-user.target"];
        wants = ["network-pre.target"];
        script = ''
          ${pkgs.macchanger}/bin/macchanger -e wlp3s0 || true
        '';
        serviceConfig.Type = "oneshot";
      };

      "zremap" = {
        description = "Intercepts keyboard udev events";
        wants = ["systemd-udevd.service"];
        wantedBy = ["multi-user.target"];
        serviceConfig.Nice = -20;
        script = ''
          sleep 1
          ${zremap.defaultPackage.${system}}/bin/zremap \
          /dev/input/by-path/platform-i8042-serio-0-event-kbd
        '';
      };

      "wakeonlan" = {
        description = "Reenable wake on lan every boot";
        after = ["network.target"];
        serviceConfig = {
          Type = "oneshot";
          ExecStart = "${pkgs.ethtool}/sbin/ethtool -s enp0s25 wol m";
        };
        wantedBy = ["default.target" "suspend.target" "shutdown.target"];
      };

      /*
      "cpu_setting" = {
        description = "Enable turboot boost and undervolt cpu after suspend";
        wantedBy = ["post-resume.target" "multi-user.target"];
        after = ["post-resume.target"];
        script = ''
                 echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
                 echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
          ${pkgs.undervolt}/bin/undervolt --core -105 --cache -105 --uncore -105 --gpu -15 -p1 47 28 -p2 57 0.0025
        '';
        serviceConfig.Type = "oneshot";
      };
      */
    };
  };

  services = {
    acpid.enable = true;
    btrfs.autoScrub.enable = true;
    dbus.enable = true;
    fstrim.enable = true;
    fwupd.enable = true;
    ntp.enable = true;
    openssh.enable = true;
    thinkfan.enable = false;

    xrdp = {
      enable = true;
      defaultWindowManager = "icewm";
      openFirewall = true;
    };

    logind = {
      lidSwitch = "ignore";
    };

    jellyfin = {
      enable = true;
      user = "akill";
      openFirewall = true;
    };

    jellyseerr = {
      enable = true;
      openFirewall = true;
    };

    pipewire = {
      enable = true;
      alsa.enable = true;
      alsa.support32Bit = true;
      pulse.enable = true;
    };

    deluge = {
      enable = false;
      user = "akill";
      openFirewall = true;
      dataDir = "/home/akill/.config/deluge";
      web = {
        enable = true;
        openFirewall = false;
      };
      config = {
        download_location = "/media";
        allow_remote = true;
        daemon_port = 58846;
      };
    };

    transmission = {
      enable = false;
      openFirewall = true;
      settings = {
        rpc-whitelist = "192.168.88.*";
        download-dir = "/media";
      };
    };

    qbittorrent = {
      enable = true;
      user = "akill";
      openFirewall = true;
      dataDir = "/home/akill/.config/qbittorrent";
      port = 8081;
    };

    nginx = {
      enable = true;
      recommendedGzipSettings = true;
      recommendedOptimisation = true;
      recommendedProxySettings = true;
      recommendedTlsSettings = true;

      virtualHosts."deluge.mediabox.lan" = {
        locations."/".proxyPass = "http://localhost:8112/";
      };
      virtualHosts."qbittorrent.mediabox.lan" = {
        locations."/".proxyPass = "http://localhost:8081/";
      };
      virtualHosts."jellyfin.mediabox.lan" = {
        locations."/".proxyPass = "http://localhost:8096/";
      };
      virtualHosts."jellyseerr.mediabox.lan" = {
        locations."/".proxyPass = "http://localhost:5055/";
      };
    };

    journald.extraConfig = ''
      SystemMaxUse=50M
    '';

    logind.extraConfig = ''
      KillUserProcesses=yes
    '';

    xserver = {
      enable = true;
      libinput.enable = true;
      desktopManager.xterm.enable = false;
      displayManager.lightdm.enable = false;
      displayManager.defaultSession = "none+icewm";
      windowManager.icewm.enable = true;
    };

    udev.packages = [];

    tlp = {
      enable = true;
      settings = {};
    };

    actkbd = {
      enable = true;
      bindings = [
        {
          keys = [121];
          events = ["key"];
          command = "${pkgs.alsaUtils}/bin/amixer -q set Master toggle";
        }
        {
          keys = [122];
          events = ["key" "rep"];
          command = "${pkgs.alsaUtils}/bin/amixer -q set Master ${config.sound.mediaKeys.volumeStep}- unmute";
        }
        {
          keys = [123];
          events = ["key" "rep"];
          command = "${pkgs.alsaUtils}/bin/amixer -q set Master ${config.sound.mediaKeys.volumeStep}+ unmute";
        }
        {
          keys = [224];
          events = ["key"];
          command = "/run/current-system/sw/bin/light -U 5";
        }
        {
          keys = [225];
          events = ["key"];
          command = "/run/current-system/sw/bin/light -A 5";
        }
      ];
    };

    mpd = {
      musicDirectory = "/home/mpd/music";
      enable = false;
      extraConfig = ''
        audio_output {
          type "pulse"
          name "pulsee srv"
          server "127.0.0.1"
        }
      '';
    };

    batteryNotifier = {
      enable = true;
      notifyCapacity = 20;
      suspendCapacity = 10;
    };

    dnscrypt-proxy2 = {
      enable = true;
      settings = {
        ipv6_servers = true;
        require_dnssec = true;

        sources.public-resolvers = {
          urls = [
            "https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md"
            "https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md"
          ];
          cache_file = "/var/lib/dnscrypt-proxy/public-resolvers.md";
          minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
        };
      };
    };
  };

  fonts.packages = with pkgs; [
    dina-font
    fira-code
    fira-code-symbols
    font-awesome
    font-awesome_4
    iosevka
    jetbrains-mono
    liberation_ttf
    proggyfonts
    siji
  ];

  virtualisation = {
    podman = {
      enable = true;
      dockerCompat = true;
    };
  };

  sound.enable = true;

  hardware = {
    bluetooth = {
      enable = false;
      settings = {
        General = {
          Enable = "Source,Sink,Media,Socket";
        };
      };
    };

    opengl = {
      enable = true;
      driSupport = true;
      driSupport32Bit = true;
      extraPackages = with pkgs; [
        intel-media-driver
        vaapiIntel
      ];
    };
  };

  zramSwap = {
    enable = false;
    algorithm = "zstd";
  };

  users.users.akill = {
    isNormalUser = true;
    shell = pkgs.zsh;
    extraGroups = ["wireshark" "wheel" "kvm" "tty" "audio" "sound" "adbusers" "transmission"];
    openssh.authorizedKeys.keys = [
      (builtins.readFile ../nixy/ssh_pubkey)
    ];
  };

  users.users.ado = {
    isNormalUser = true;
    shell = pkgs.zsh;
    extraGroups = ["wireshark" "wheel" "kvm" "tty" "audio" "sound" "adbusers" "transmission"];
  };

  users.users.mediauser = {
    isNormalUser = true;
    shell = pkgs.bash;
    extraGroups = [];
  };
}