{ inputs, config, lib, pkgs, outputs,... }:
let
  pubKeys = lib.filesystem.listFilesRecursive (../common/users/keys);
  secretsDirectory = builtins.toString inputs.nix-secrets;
  secretsFile = "${secretsDirectory}/secrets.yaml";
  sopsHashedPasswordFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."passwords/root".path;
  hasOptinPersistence = config.environment.persistence ? "/persist";
  
  # Disko setup
  fsType = "btrfs";
  dev = "/dev/vda";
  encrypted = true;
  btrfsMountDevice = if encrypted then "/dev/mapper/crypted" else "/dev/root_vg/root";
in
{
  imports =
    [
      # Disk configuration
      inputs.sops-nix.nixosModules.sops

      # Disk configuration
      inputs.disko.nixosModules.disko
      (import ../common/disks { device = dev; fsType = fsType; encrypted = encrypted; })

      # Impermanence
      inputs.impermanence.nixosModules.impermanence
      (import ../common/disks/btrfs-impermanence.nix { btrfsMountDevice = btrfsMountDevice; lib = lib; })

      # Import core options
      ./hardware-configuration.nix
    ];

  nixpkgs = {
      overlays = [
        outputs.overlays.additions
        outputs.overlays.modifications
        outputs.overlays.unstable-packages
      ];
      config = {
        allowUnfree = true;
      };
    };

  fileSystems."/persist".neededForBoot = true;
  environment.persistence."/persist" = {
    hideMounts = true;
    directories = [
      "/etc/nixos"
    ];
    files = [
      "/etc/ssh/ssh_host_ed25519_key"
      "/etc/ssh/ssh_host_ed25519_key.pub"
    ];
  };

  i18n.defaultLocale = "en_GB.UTF-8";
  console = {
    font = "Lat2-Terminus16";
    keyMap = "uk";
    useXkbConfig = false;
  };


  boot = {
    loader = {
      systemd-boot.enable = true;
      efi.canTouchEfiVariables = true;
      timeout = 3;
    };
  };

  users = {
    mutableUsers = true;
    extraUsers = {
      root = {
        hashedPasswordFile = sopsHashedPasswordFile;
        openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
      };
     };
  };

  networking = {
    hostName = "bootstrap";
    networkmanager.enable = true;
    enableIPv6 = false;
  };

  sops = {
    defaultSopsFile = "${secretsFile}";
    validateSopsFiles = false;

    age = {
      sshKeyPaths = [ "${lib.optionalString hasOptinPersistence "/persist"}/etc/ssh/ssh_host_ed25519_key" ];
    };
    secrets =  {
        "passwords/root".neededForUsers = true;
        "ssh_keys/deploy_key/id_ed25519" = {
          path = "/etc/ssh/deploy_key-ssh-ed25519";
        };
    };
  };

  environment.systemPackages = [
      pkgs.rsync
      pkgs.curl
      pkgs.just
      pkgs.git
      pkgs.neovim
  ];

  services.openssh = {
    enable = true;
    ports = [22];
    authorizedKeysFiles = lib.mkForce ["/etc/ssh/authorized_keys.d/%u"];
    hostKeys = [{
      path = "${lib.optionalString hasOptinPersistence "/persist"}/persist/etc/ssh/ssh_host_ed25519_key";
      type = "ed25519";
    }];
    settings = {
      PasswordAuthentication = false;
      PermitRootLogin = "yes";
      PubKeyAuthentication = "yes";
      StreamLocalBindUnlink = "yes";
      UsePAM = true;
    };
  };

  programs.ssh.extraConfig = ''
    Host git.bitlab21.com
        IdentitiesOnly yes
        StrictHostKeyChecking no
        IdentityFile /etc/ssh/deploy_key-ssh-ed25519
  '';

  security.pam = {
    sshAgentAuth.enable = true;
  };

  networking.firewall.allowedTCPPorts = [ 22 ];

  services = {
    qemuGuest.enable = true;
  };

  nix.settings.experimental-features = [ "nix-command" "flakes" ];
}