# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page, on
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).

{ pkgs, lib, ... }:

let
  emile_keys = [
    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPZi43zHEsoWaQomLGaftPE5k0RqVrZyiTtGqZlpWsew emile@caladan"
    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEzLZ56SEgwZZ0OusTdSDDhpMlxSg1zPNdRLuxKOfrR5 emile@chusuk"
    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMoHWyC9r0LVk6UlkhBWAJph0F6KHYHh83EI5U9wtfq2 shortcuts@ginaz"
  ];
in
{
  imports = [
    # Include the results of the hardware scan.
    ./hardware-configuration.nix
  ];

  boot = {
    loader = {
      systemd-boot.enable = true;
      efi.canTouchEfiVariables = true;
    };
    kernelParams = [ "ip=dhcp" ];
    initrd = {
      availableKernelModules = [ "r8169" ];
      systemd.users.root.shell = "/bin/cryptsetup-askpass";
      network = {
        enable = true;
        ssh = {
          enable = true;
          port = 22;
          hostKeys = [ "/initrd_ssh_host_key_ed25519" ];
          authorizedKeys = emile_keys;
        };
        postCommands = ''
          echo 'cryptsetup-askpass' > /root/.profile
        '';
      };
      luks.devices = {
        # unsure why luksdata1 is recognized and added to the
        # hardware-configuration.nix automatically, but luksdata2 isn't 
        "luksdata2".device = "/dev/disk/by-uuid/e94d7f32-26ef-41e1-b3f3-9e63e4858001";
      };
    };
  };

  fileSystems = {
    "/".options = [ "compress=zstd" ];
    "/home".options = [ "compress=zstd" ];
    "/nix".options = [
      "compress=zstd"
      "noatime"
    ];
  };

  networking = {
    hostName = "lampadas";
    firewall.enable = true;

    firewall.allowedTCPPorts = [
      # 5201 # iperf
      8080 # filebrowser web
    ];
    firewall.allowedUDPPorts = [
      # 5201
    ];

    nameservers = [
      "8.8.8.8"
      "8.8.4.4"
      "1.1.1.1"
    ];
  };

  time.timeZone = "Europe/Berlin";

  powerManagement = {
    powertop.enable = true;
    scsiLinkPolicy = "med_power_with_dipm";
  };

  users = {
    mutableUsers = false;
    users = {
      root = {
        hashedPassword = "";
        openssh.authorizedKeys.keys = emile_keys;
      };
      emile = {
        isNormalUser = true;
        extraGroups = [
          "wheel"
          "samba-guest"
        ];
        openssh.authorizedKeys.keys = emile_keys;
      };
      samba-guest = {
        isSystemUser = true;
        description = "Samba guest user";
        group = "samba-guest";
        home = "/var/empty";
        createHome = false;
        shell = pkgs.shadow;
      };
    };
  };
  users.groups.samba-guest = { };

  systemd.tmpfiles.rules = [
    "d /data 0755 root root"
    "d /data/private 0755 emile users"
    "d /data/public 0755 samba-guest samba-guest"
    "d /data/time_machine 0755 emile users"
  ];

  environment.systemPackages = with pkgs; [
    vim
    tailscale
    nmap
    ffuf
    git
    unzip
  ];

  programs.mosh.enable = true;

  services = {
    emile = {
      filebrowser = {
        enable = true;
        address = "192.168.1.196";
        port = 8080;
        root = "/data";
      };
    };
  
    # traffic metrics
    vnstat.enable = true;

    # ssh access
    openssh = {
      enable = true;
      settings = {
        PasswordAuthentication = false;
        KbdInteractiveAuthentication = false;
      };
    };

    # VPN
    tailscale.enable = true;

    # filesystem stuff
    btrfs.autoScrub = {
      enable = true;
      interval = "weekly";
    };

    # metric exporters
    prometheus.exporters = {
      node.enable = true; # port 9100
      systemd.enable = true; # port 9558
      smartctl.enable = true; # port 9633
    };

    # shares

    # Disable delayed TCP ACK
    # ; sysctl -w net.inet.tcp.delayed_ack=0

    # Don't write .DS_Store to network shares
    # ; defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool TRUE
    samba = {
      enable = true;
      openFirewall = true;
      settings = {
        global = {
          "security" = "user";
          "passwd program" = "/run/wrappers/bin/passwd %u";
          "invalid users" = ["root"];

          "workgroup" = "WORKGROUP";
          "server string" = "lampadas";
          "netbios name" = "lampadas";
          "hosts allow" = [
            "100.64.0.0/255.192.0.0"
            "127.0.0.1/255.0.0.0"
            "::1"
            "192.168.0."
            "192.168.1."
          ];
          "hosts deny" = "0.0.0.0/0";
          "guest account" = "samba-guest";
          "map to guest" = "bad user";
          "load printers" = "no";
          "server min protocol" = "SMB3";
          "server smb encrypt" = "required";
          "min receivefile size" = "16384";
          "use sendfile" = "yes";
          "aio read size" = "16384";
          "aio write size" = "16384";
          "server multi channel support" = "yes";
          "socket options" = [
            "TCP_NODELAY"
            "IPTOS_LOWDELAY"
            "SO_RCVBUF=131072"
            "SO_SNDBUF=131072"
          ];
          "read raw" = "yes";
          "write raw" = "yes";
          "large readwrite" = "yes";
          "getwd cache" = "yes";
          "deadtime" = "30";

          # make SMB work faster when being accessed from macos
          "file_ids_off" = "yes";
          "signing_required" = "no";
        };
        
        private = {
          "path" = "/data/private";
          "comment" = "private data (no flags though)";

          "browseable" = "yes";
          "create mask" = "0644";
          "directory mask" = "0755";
          "force user" = "emile";
          "guest ok" = "no";
          "read only" = "no";

          # "fruit:aapl" = "yes";
          # "fruit:copyfile" = "yes";
          # "fruit:delete_empty_adfiles" = "yes";
          # "fruit:metadata" = "stream";
          # "fruit:posix_rename" = "yes";
          # "fruit:time machine" = "yes";
          # "fruit:veto_appledouble" = "no";
          # "fruit:wipe_intentionally_left_blank_rfork" = "yes";
          # "fruit:nfs_aces" = "no";
          # "fruit:zero_file_id" = "yes";
          # "fruit:encoding" = "native";
        };

        public = {
          "path" = "/data/public";
          "comment" = "public data";

          "available" = "yes";
          "browseable" = "yes";
          "create mask" = "2775";
          "directory mask" = "2775";
          "force user" = "samba-guest";
          "guest ok" = "yes";
          "guest only" = "yes";
          "read only" = "no";
          "writable" = "yes";
        };

        time_machine = {
          "path" = "/data/time_machine";
          "comment" = "time machine backups";

          "force user" = "emile";
          "fruit:aapl" = "yes";
          "fruit:copyfile" = "yes";
          "fruit:delete_empty_adfiles" = "yes";
          "fruit:metadata" = "stream";
          "fruit:posix_rename" = "yes";
          "fruit:time machine" = "yes";
          "fruit:veto_appledouble" = "no";
          "fruit:wipe_intentionally_left_blank_rfork" = "yes";
          "fruit:nfs_aces" = "no";
          # "fruit:zero_file_id" = "yes";
          # "fruit:encoding" = "native";
          "public" = "no";
          "valid users" = "emile";
          "vfs objects" = ["catia" "fruit" "streams_xattr"];
          "writeable" = "yes";
        };
      };
    };
  };

  system = {
    stateVersion = "23.11";
    autoUpgrade.enable = true;
  };

  nix = {
    settings.experimental-features = [
      "nix-command"
      "flakes"
    ];
    gc = {
      automatic = true;
      dates = "weekly";
      options = "--delete-older-than 14d";
    };
    settings = {
      auto-optimise-store = true;
    };
  };
}