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

{ config, 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
  ];

  hardware.fancontrol = {
    enable = true;
    config = ''
      # Configuration file generated by pwmconfig, changes will be lost
      INTERVAL=10
      DEVPATH=hwmon0=devices/platform/coretemp.0 hwmon1=devices/platform/nct6775.672
      DEVNAME=hwmon0=coretemp hwmon1=nct6798
      FCTEMPS=hwmon1/pwm3=hwmon0/temp2_input hwmon1/pwm2=hwmon1/temp2_input
      FCFANS=hwmon1/pwm3=hwmon1/fan3_input hwmon1/pwm2=hwmon1/fan2_input
      MINTEMP=hwmon1/pwm3=35 hwmon1/pwm2=35
      MAXTEMP=hwmon1/pwm3=75 hwmon1/pwm2=75
      MINSTART=hwmon1/pwm3=255 hwmon1/pwm2=255
      MINSTOP=hwmon1/pwm3=30 hwmon1/pwm2=30
      MINPWM=hwmon1/pwm3=30 hwmon1/pwm2=30
      MAXPWM=hwmon1/pwm3=255 hwmon1/pwm2=255
    '';
  };

  boot = {
    loader = {
      systemd-boot.enable = true;
      efi.canTouchEfiVariables = true;
    };
    kernelParams = [ "ip=dhcp" ];
    kernelModules = [
      # fan speed modules, detected using `sensors-detect`
      "coretemp" "nct6775"
    ];
    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 # iperf
    ];

    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";
        address = "100.87.209.97";
        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 = {
      enable = true;
      port = 9090;
      listenAddress = "100.87.209.97";
      scrapeConfigs = [
        {
          job_name = "node";
          static_configs = [{
            targets = [
              "localhost:${toString config.services.prometheus.exporters.node.port}"
            ];
          }];
        }  
        {
          job_name = "systemd";
          static_configs = [{
            targets = [
              "localhost:${toString config.services.prometheus.exporters.systemd.port}"
            ];
          }];
        }  
        {
          job_name = "smartctl";
          static_configs = [{
            targets = [
              "localhost:${toString config.services.prometheus.exporters.smartctl.port}"
            ];
          }];
        }  
      ];
      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 = {

          ## Browsing/Identification ###
          "workgroup" = "Pacific";
          "server string" = "lampadas";
          "disable netbios" = "yes";

          #### Debugging/Accounting ####
          "log level" = "0";
          "max log size" = "1000";
          "logging" = "file";
          "log file" = "/dev/null";

          ####### Authentication #######
          "server role" = "standalone server";
          "obey pam restrictions" = "yes";
          "unix password sync" = "yes";
          "passwd program" = "/usr/bin/env passwd %u";
          "passwd chat" = "*Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .";
          "pam password change" = "yes";
          "map to guest" = "bad user";

          "ea support" = "yes";
          "client ipc signing" = "disabled";
          "aio max threads" = "200";
          "aio read size" = "1";
          "aio write size" = "1";

          # optimization adapted from https://docs.openmediavault.org/en/latest/administration/services/samba.html
          "load printers" = "no";
          "disable spoolss" = "yes";
          "printing" = "bsd";
          "printcap name" = "/dev/null";
          "time server" = "no";
          "wins support" = "no";


          # random other settings that seem to make sense
          "server min protocol" = "SMB3";
          "security" = "user";
          "invalid users" = ["root"];
          "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";
          "server smb encrypt" = "required";
          "min receivefile size" = "65536";
          "use sendfile" = "yes";
          "server multi channel support" = "yes";
          "socket options" = [
            "TCP_NODELAY"
            "IPTOS_LOWDELAY"
            "SO_RCVBUF=67108864"
            "SO_SNDBUF=67108864"
          ];
          "read raw" = "yes";
          "write raw" = "yes";
          "large readwrite" = "yes";
          "getwd cache" = "yes";
          "deadtime" = "30";
          "store dos attributes" = "yes";
          "dns proxy" = "no";
          "map hidden" = "no";
          "map system" = "no";
          "map archive" = "no";
          "nt acl support" = "yes";

          "inherit acls" = "yes";
          "map acl inherit" = "yes";
          "encrypt passwords" = "yes";
          "client plaintext auth" = "no";

          # 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";

          # macOS / iOS config, adaption from https://wiki.samba.org/index.php/Configure_Samba_to_Work_Better_with_Mac_OS_X
          "fruit:metadata" = "stream";
          "fruit:model" = "MacSamba";
          "fruit:posix_rename" = "yes";
          "fruit:veto_appledouble" = "no";
          "fruit:nfs_aces" = "no";
          "fruit:wipe_intentionally_left_blank_rfork" = "yes";
          "fruit:delete_empty_adfiles" = "yes";
          "fruit:encoding" = "private";
          "fruit:locking" = "none";
          "fruit:resource" = "file";

          "force user" = "emile";
          "fruit:aapl" = "yes";
          "fruit:copyfile" = "yes";
          "fruit:time machine" = "yes";
          # "fruit:zero_file_id" = "yes";
          "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;
    };
  };
}