{
  config,
  lib,
  pkgs,
  namespace,
  ...
}:
let
  inherit (lib.${namespace}) enabled disabled;
in
{
  imports = [
    ./boot.nix
    ./apps.nix
    ./users.nix
    ./services.nix
    ./sops.nix
  ];

  services.kmscon = disabled;

  powerManagement.cpuFreqGovernor = "powersave";

  ${namespace} = {
    # ###################################################
    # #                     Boot                      # #
    # ###################################################

    bootloader.lanzaboote = enabled;

    # ###################################################
    # #                   Desktop                     # #
    # ###################################################

    desktop.cosmic = enabled;

    # ###################################################
    # #                 Development                   # #
    # ###################################################

    development = {
      enable = true;
      includeLanguages = [
        "python"
        "c"
      ];
      includeContainers = true;
    };

    gaming.enable = true;

    # ###################################################
    # #                   Hardware                    # #
    # ###################################################

    hardware = {
      disko = {
        enable = true;
        enableSwap = false;
        enableLuks = true;
      };

      amd = {
        enable = true;
      };
    };

    headless.enable = true;

    # ###################################################
    # #                 Impermanence                  # #
    # ###################################################

    impermanence = {
      enable = true;
      extraDirectories = [
        # {
        #   directory = "/var/lib/private/authentik/media";
        #   user = "authentik";
        #   group = "authentik";
        #   mode = "u=rwx,g=,o=";
        # }
        {
          directory = "/var/lib/crowdsec";
          user = "crowdsec";
          group = "crowdsec";
          mode = "u=rwx,g=rwx,o=rx";
        }
        {
          directory = "/var/lib/nextcloud";
          user = "nextcloud";
          group = "nextcloud";
          mode = "u=rwx,g=rwx,o=rx";
        }
        {
          directory = "/plugins-storage";
          user = "traefik";
          group = "traefik";
          mode = "u=rwx,g=rwx,o=rx";
        }
      ];
    };

    # ###################################################
    # #                  Monitoring                   # #
    # ###################################################

    monitoring = enabled;

    # ###################################################
    # #                    Network                    # #
    # ###################################################

    network = {
      hostName = "jallen-nas";
      ipv4 = {
        address = "10.0.1.3";
        method = "manual";
        gateway = "10.0.1.1";
        interface = "enp197s0";
      };
      hostId = "4b501480";
      nat = {
        enable = true;
        internalInterfaces = [ "ve-+" ];
        externalInterface = "enp197s0";
        enableIPv6 = true;
      };
      firewall = {
        enable = true;
        allowPing = true;
        trustedInterfaces = [ "tailscale0" ];
        allowedTCPPorts = [
          8008 # restic
          9000 # authentik
          2342 # grafana
          51820 # wireguard
          1025
          1143
          10200
          10300
          8127
          8280
          9943 # onlyoffice
          4000 # netbootxyz
          4080 # netbootxyz
          3000 # gitea
          2222 # gitea ssh
          3300
          9898
          6754 # lubelogger
          2283 # immich
          4444 # code-server
          9012
          9988
          8192
          3000
          2222
          8181
          5432
          3001
          3333
          5201 # iperf
          8400
          9200
          9233
          9980
          47984
          47989
          47990
          47998
          47999
          48000
          48010
        ];
        allowedUDPPorts = config.${namespace}.network.firewall.allowedTCPPorts;
      };
    };

    # ###################################################
    # #                    Power                      # #
    # ###################################################

    power.ups = enabled;

    # ###################################################
    # #                    Samba                      # #
    # ###################################################

    samba = {
      enable = true;
      hostsAllow = "10.0.1.";
      enableTimeMachine = true;
      timeMachinePath = "/media/nas/main/timemachine";

      shares = {
        "3d_printer" = {
          public = true;
          sharePath = "/media/nas/main/3d_printer";
        };
        Backup = {
          public = true;
          sharePath = "/media/nas/main/backup";
        };
        Documents = {
          public = true;
          sharePath = "/media/nas/main/documents";
        };
        isos = {
          public = true;
          sharePath = "/media/nas/main/isos";
        };
        TimeMachine = {
          public = false;
          sharePath = "/media/nas/main/timemachine";
          enableTimeMachine = true;
          timeMachineMaxSize = "1T";
        };
        app_data = {
          public = true;
          sharePath = "/media/nas/main/ssd_app_data";
        };
        nix-config = {
          public = true;
          sharePath = "/home/matt/nix-config";
        };
      };
    };

    # ###################################################
    # #                   Security                    # #
    # ###################################################

    security.tpm = enabled;

    # ###################################################
    # #                   Services                    # #
    # ###################################################

    services = {
      grafana = {
        enable = true;
        port = 9999;
      };
    };

    # ###################################################
    # #                     User                      # #
    # ###################################################

    user = {
      name = "admin";
      hashedPasswordFile = config.sops.secrets."jallen-nas/admin_password".path;
      linger = true;
      extraGroups = [
        "nix-apps"
        "jallen-nas"
        "grafana"
        "traefik"
        "62900"
        "1001"
      ];
    };
  };

  # ###################################################
  # #                    Mounts                     # #
  # ###################################################
  fileSystems."/media/nas/main" = {
    label = "nas_pool";
    # device = "/dev/sde:/dev/sdf:/dev/sdh:/dev/sdi:/dev/sdj:/dev/nmve0n1:/dev/nvme1n1";
    fsType = "bcachefs";
    mountPoint = "/media/nas/main";
    options = [
      # "noauto"
      "nofail"
      # "x-systemd.mount-timeout=0"
      # "x-systemd.device-timeout=0"
    ];
  };

  boot.initrd.luks.devices.cryptroot.device = "/dev/disk/by-partlabel/disk-main-jallen-nas-cryptroot";

  # Configure environment
  environment = {
    systemPackages = with pkgs; [
      attic-client
      bcachefs-tools
      cryptsetup
      clevis
      deconz
      duperemove
      efibootmgr
      ffmpeg
      ipset
      keyutils
      nut
      packagekit
      pass
      protonmail-bridge
      protonvpn-gui
      qrencode
      rcon
      sbctl
      tigervnc
      tpm2-tools
      tpm2-tss
    ];
    persistence."/media/nas/main/persist" = {
      hideMounts = true;
      directories = [
        {
          directory = "/var/cache/ccache";
          user = "nobody";
          group = "nobody";
          mode = "u=rwx,g=rwx,o=rx";
        }
        {
          directory = "/var/lib/redis-ccache";
          user = "redis-ccache";
          group = "redis-ccache";
          mode = "u=rwx,g=,o=";
        }
      ];
    };
  };

  # Configure programs
  programs = {
    kdeconnect.enable = lib.mkForce false;
    virt-manager.enable = true;
  };
}
