# Specifications For Secret Data Structures
{
  pkgs,
  config,
  lib,
  ...
}:
let
  # Function to create a private key file in the Nix store with proper permissions
  mkSshKeyFile =
    name: content:
    pkgs.writeTextFile {
      name = "ssh-key-${name}";
      text = content;
      executable = false;
      checkPhase = ''
        # Verify it's a valid SSH key (optional)
        grep -q "BEGIN OPENSSH PRIVATE KEY" "$out" || (echo "Invalid SSH key format"; exit 1)
      '';
    };
in
{
  options.secretsSpec = {
    ssh = lib.mkOption {
      type = lib.types.submodule {
        options = {
          # privateKeys are set up automagically 🌠, see config below
          privateKeyContents = lib.mkOption {
            type = lib.types.attrsOf lib.types.str;
            description = "SSH private key contents keyed by name";
            default = { };
          };
          privateKeys = lib.mkOption {
            type = lib.types.attrsOf lib.types.path;
            description = "SSH private key file paths keyed by name";
            # default = { };
            readOnly = true;
          };
          publicKeys = lib.mkOption {
            type = lib.types.attrsOf lib.types.str;
            description = "SSH public keys keyed by name";
            default = { };
          };
          knownHosts = lib.mkOption {
            type = lib.types.listOf lib.types.str;
            description = "SSH known hosts entries";
            default = [ ];
          };
        };
      };
      default = { };
      description = "SSH key related secrets";
    };

    api = lib.mkOption {
      type = lib.types.attrsOf lib.types.str;
      description = "API keys keyed by service name";
      default = { };
    };

    docker = lib.mkOption {
      type = lib.types.attrsOf (lib.types.attrsOf lib.types.str);
      description = "Docker environment variables keyed by container name";
      default = { };
    };

    users = lib.mkOption {
      type = lib.types.attrsOf (
        lib.types.submodule {
          options = {
            hashedPassword = lib.mkOption {
              type = lib.types.str;
              description = "Hashed password for the user"; # nix-shell -p whois --run 'mkpasswd --method=sha-512 --rounds=656000'
            };
            email = lib.mkOption {
              type = lib.types.str;
              description = "Email address for the user";
            };
            handle = lib.mkOption {
              type = lib.types.str;
              description = "The handle of the user (eg: github user)";
            };
            fullName = lib.mkOption {
              type = lib.types.str;
              description = "Full name of the user";
            };
            sshKeys = lib.mkOption {
              type = lib.types.listOf lib.types.str;
              description = "SSH public keys for the user";
              default = [ ];
            };
          };
        }
      );
      description = "User information secrets";
      default = { };
    };

    firewall = lib.mkOption {
      type = lib.types.attrsOf (
        lib.types.submodule {
          options = {
            allowedTCPPorts = lib.mkOption {
              type = lib.types.listOf lib.types.port;
              description = "Allowed TCP ports for this host";
              default = [ ];
              # example = [
              #   22
              #   80
              #   443
              # ];
            };
            allowedTCPPortRanges = lib.mkOption {
              type = lib.types.listOf (
                lib.types.submodule {
                  options = {
                    from = lib.mkOption {
                      type = lib.types.port;
                      description = "Starting port in range";
                    };
                    to = lib.mkOption {
                      type = lib.types.port;
                      description = "Ending port in range";
                    };
                  };
                }
              );
              description = "Allowed TCP port ranges for this host";
              default = [ ];
              # example = [
              #   {
              #     from = 25565;
              #     to = 25570;
              #   }
              # ];
            };
            allowedUDPPorts = lib.mkOption {
              type = lib.types.listOf lib.types.port;
              description = "Allowed UDP ports for this host";
              default = [ ];
              # example = [
              #   53
              #   123
              # ];
            };
            allowedUDPPortRanges = lib.mkOption {
              type = lib.types.listOf (
                lib.types.submodule {
                  options = {
                    from = lib.mkOption {
                      type = lib.types.port;
                      description = "Starting port in range";
                    };
                    to = lib.mkOption {
                      type = lib.types.port;
                      description = "Ending port in range";
                    };
                  };
                }
              );
              description = "Allowed UDP port ranges for this host";
              default = [ ];
              # example = [
              #   {
              #     from = 25565;
              #     to = 25570;
              #   }
              # ];
            };
          };
        }
      );
      description = "Firewall configuration by host";
      default = { };
    };
  };

  config.secretsSpec.ssh.privateKeys = lib.mapAttrs (
    name: content: mkSshKeyFile name content
  ) config.secretsSpec.ssh.privateKeyContents;
}
