{ lib, pkgs, config, ... }:
with lib;                      
let
  cfg = config.kevin.ssh;
  authorizedOpts = {name, config, ...}: {
    options = {
      users = mkOption {
        type = with types; listOf types.str;
        default = [];
        example = [
          "kevin"
          "root"
        ];
        description = "Accounts this SSH key should have access to";
      };
    };
  };
in {

  options.kevin.ssh = {
    server.enable = mkEnableOption "kevins ssh";
    authorized = mkOption {
      default = {};
      type = with types; attrsOf (submodule authorizedOpts);
      example = {
        kevin = {
          users = [ "kevin" "root" ];
        };
      };
      description = "Object containing users and the accounts they are authorized for.";
    };
  };

  config = mkMerge [
    (mkIf cfg.server.enable {
      services.openssh = {
        enable = true;
        # require public key authentication for better security
        settings = {
          PasswordAuthentication = false;
          KbdInteractiveAuthentication = false;
        };
        #permitRootLogin = "yes";
      };
      
      networking.firewall.allowedTCPPorts = [ 22 ];
    })
    {
      users.users = mkMerge (map (name: (
        mkMerge (
          map (user: {
            "${user}".openssh.authorizedKeys.keys = 
              (lib.strings.splitString "\n" 
                (lib.strings.removeSuffix "\n" 
                  (builtins.readFile (./. + "/../../ssh/${name}/authorized_keys"))));
          }) cfg.authorized."${name}".users
        )
      )) (attrNames cfg.authorized));
    }
  ];
}