# 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’).
{ pkgs
, inputs
, ...
}: {
  imports = [
    ./disko.nix
  ];

  facter.reportPath = ./facter.json;

  my = {
    ai.enable = true;
    virtualisation.libvirtd.enable = true;
    yubikey.luksSupport.enable = false;
    profiles = {
      desktop.enable = true;
      personal.enable = true;
      personal.mail = true;
      personal.contacts = true;
      personal.calendar = true;
      webis.enable = true;
      impermanence.enable = true;
    };
    programs.exercism.enable = true;
    services.mullvad.enable = true;
  };

  users.users.moritz.packages = with pkgs; [
    poetry
    wl-clipboard
  ];

  home-manager.users.moritz.services.kanshi.settings = [
    {
      profile.name = "undocked";
      profile.outputs = [
        {
          criteria = "eDP-1";
          scale = 1.0;
        }
      ];
    }
    {
      profile.name = "docked-scads";
      profile.outputs = [
        {
          criteria = "eDP-1";
          position = "640,1800"; # NOTE: 2160 / 1.2 = 1800
        }
        {
          criteria = "Dell Inc. DELL P4317Q";
          scale = 1.2;
          position = "0,0";
        }
      ];

    }
  ];

  services.kanata = {
    enable = true;
    keyboards = {
      laptop = {
        devices = [
          "/dev/input/by-path/platform-i8042-serio-0-event-kbd"
        ];
        config = "
          (defsrc
            grv  1    2    3    4    5    6    7    8    9    0    -    =    bspc
            tab  q    w    e    r    t    y    u    i    o    p    [    ]    \
            caps a    s    d    f    g    h    j    k    l    ;    '    ret
            lsft z    x    c    v    b    n    m    ,    .    /    rsft
            lctl lmet lalt           spc            ralt      rctl
          )

          (deflayermap (default)
            ;; tarmak 1a
            j n
            n k
            k e

            ;; tarmak 1b
            h m
            m h

            ;; tarmak 2a
            b z
            z x
            x c

            ;; tarmak 2b
            e f
            f t
            t b

            ;; tarmak 3
            c d
            d s
            s r

            ;; tarmak 4
            r p
            p ;
            ; o
            o y
            y j

            ;; tarmak 5
            u l
            l i
            i u

            ;; caps-word tap-dance
            lsft (tap-dance 200 (_ (caps-word 2000) _ _))

            ;; change ctrl alt and meta
            lctl lalt
            lmet lctl
            lalt (tap-dance 200 (lmet (multi lmet alt) lmet lmet))

            ;; hjkl layer
            ralt (tap-hold 200 200 (layer-switch hjkl) (layer-while-held hjkl)) ;; tap: switch   hold: switch while held

            ;; switch to normal keyboard layout
            rctl (layer-switch normal)
          )

          (deflayermap (normal)
            rctl (layer-switch default))

          (deflayermap (hjkl)
            h left
            j down
            k up
            l right

            ralt (layer-switch default))
        ";
      };
    };
  };

  # BOOT
  boot = {
    supportedFilesystems = [ "zfs" ];
    loader.systemd-boot.enable = true;
    loader.efi.canTouchEfiVariables = true;
    initrd.availableKernelModules = [ "rtsx_pci_sdmmc" ];
  };

  # SERVICES
  services = {
    libinput.enable = true;
    libinput.touchpad.disableWhileTyping = true;
    printing.enable = true;
    logind.lidSwitch = "hybrid-sleep";
  };

  # NETWORKING
  networking = {
    hostName = "nixos-laptop";
    networkmanager.enable = true;

    useDHCP = false;
    interfaces.wlp1s0.useDHCP = true;
    # interfaces.enp4s0f4u2.useDHCP = true;
  };

  time.timeZone = "Europe/Berlin";
  console.keyMap = "de";

  # needed for enabling hibernation
  security.protectKernelImage = false;

  # Powersaving
  services.tlp.enable = true;
  powerManagement.enable = true;
  powerManagement.powertop.enable = true;

  systemd = {
    # Hibernare on low battery
    timers.hibernate-on-low-battery = {
      wantedBy = [ "multi-user.target" ];
      timerConfig = {
        OnUnitActiveSec = "120";
        OnBootSec = "120";
      };
    };
    services.hibernate-on-low-battery =
      let
        batteryLevelSufficient =
          let
            batteryPath = "/sys/class/power_supply/BATT";
          in
          pkgs.writeShellScriptBin "battery-level-sufficient" ''
            test "$(cat ${batteryPath}/status)" != Discharging \
              || test "$(cat ${batteryPath}/capacity)" -ge 5
          '';
      in
      {
        serviceConfig.Type = "oneshot";
        onFailure = [ "hibernate.target" ];
        script = "${batteryLevelSufficient}/bin/battery-level-sufficient";
      };
    services.asus-touchpad-numpad = {
      description = "Activate Numpad inside the touchpad with top right corner switch";
      documentation = [ "https://github.com/mohamed-badaoui/asus-touchpad-numpad-driver" ];
      path = [ pkgs.i2c-tools ];
      script = ''
        cd ${inputs.asus-touchpad-numpad-driver}
        # In the last argument here you choose your layout.
        ${
          pkgs.python3.withPackages (ps: [ps.libevdev])
        }/bin/python asus_touchpad.py m433ia
      '';
      # Probably needed because it fails on boot seemingly because the driver
      # is not ready yet. Alternatively, you can use `sleep 3` or similar in the
      # `script`.
      serviceConfig = {
        RestartSec = "1s";
        Restart = "on-failure";
      };
      wantedBy = [ "multi-user.target" ];
    };
  };

  # Trackpad
  # i2c for https://github.com/mohamed-badaoui/asus-touchpad-numpad-driver
  hardware.i2c.enable = true;

  # 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 = "22.05"; # Did you read the comment?
}
