{ config, lib, pkgs, ... }:

with lib;

let
  cfg = config.hacc.websites;
in

{
  options.hacc.websites = {
    enable = mkOption {
      type = types.bool;
      default = false;
    };
    directory = mkOption {
      type = types.path;
      description = "all subdirectories of the given path are expected to contain a (static) website";
    };
    ignore = mkOption {
      type = types.listOf types.str;
      default = [];
      description = "subdirectories that shouldn't be published";
    };
    builders = mkOption {
      type = types.lazyAttrsOf types.package;
      default = {};
      description = "exposes website builders, for use with nix run";
    };
  };

  config = let
    subdirs =
      let dirAttrs = filterAttrs
        (n: v: v == "directory" || lists.elem n cfg.ignore)
        (builtins.readDir cfg.directory);
      in mapAttrsToList (n: v: n) dirAttrs;
    mkWebsiteDrv = subdir:
      pkgs.callPackage "${cfg.directory}/${subdir}" {};
    mkWebsiteVHost = subdir: {
      name = subdir;
      # the nginx virtualhost config (for all sites) goes in here
      value = {
        enableACME = true;
        forceSSL = true;

        locations."/".root =
          (mkWebsiteDrv subdir).outPath;
      };
    };
  in mkIf cfg.enable {
    services.nginx = {
      enable = true;
      virtualHosts =
        listToAttrs (map mkWebsiteVHost subdirs);
    };
    hacc.websites.builders =
      listToAttrs (map (subdir: {
        name = subdir;
        value = if (mkWebsiteDrv subdir) ? watch then (mkWebsiteDrv subdir).watch else null;
      }) subdirs);
  };
}