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

let
  cfg = config.samfelag.modules.server.consul;
  nameservers = config.networking.nomeservers;
in
{
  options.samfelag.modules.server.consul = {
    enable = lib.mkEnableOption "consul";

    server = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = "Set to true if configured a server - otherwise a client is assumed";
    };

    agent-token = lib.mkOption {
      type = lib.types.str;
      description = "Agent token config file (should be secret)";
    };

    server-cert = lib.mkOption {
      type = lib.types.str;
      description = "Server certificate (should be secret)";
    };

    server-cert-key = lib.mkOption {
      type = lib.types.str;
      description = "Server certificate key (should be secret)";
    };

  };
  config = lib.mkIf cfg.enable {
    services.consul = {
      enable = true;
      webUi = true;
    } // lib.optionalAttrs cfg.server {
      extraConfig = {
        recursors = config.networking.nameservers;
      };
    };

    # --- Systemd patch --------------------------------

    systemd.services.consul = {
      after = [ "sys-subsystem-net-devices-tailscale0.device" "tailscaled.service" ];
      requires = [ "tailscaled.service" ];
    };

    # --- Config files ---------------------------------

    environment.etc = {
      consul-agent-ca = {
        # Consul agent CA
        target = "consul.d/certs/consul-agent-ca.pem";
        source = config.age.secrets."consul.d/consul-agent-ca.pem".path;
      };
      consul-gossip = {
        # Gossip encryption key
        target = "consul.d/gossip.json";
        source = config.age.secrets."consul.d/gossip.json".path;
      };
      consul-common-cfg = {
        # Common config
        target = "consul.d/common.json";
        source = ../../config/consul.d/common.json;
      };
      consul-server-list = {
        # Server list
        target = "consul.d/server-list.json";
        source = ../../config/consul.d/server-list.json;
      };
      consul-agent-token = {
        # Agent token
        target = "consul.d/agent-token.json";
        source = cfg.agent-token;
      };
    } // (if cfg.server then {
      consul-server-cfg = {
        # Server config
        target = "consul.d/server.json";
        source = ../../config/consul.d/server.json;
      };
      consul-server-cert = {
        # Consul Server Certificate
        target = "consul.d/certs/samfelag-server-consul.pem";
        source = cfg.server-cert;
      };
      consul-server-cert-key = {
        # Consul Server Certificate Key
        target = "consul.d/certs/samfelag-server-consul-key.pem";
        source = cfg.server-cert-key;
      };
    } else {
      consul-client-cfg = {
        # Client config
        target = "consul.d/client.json";
        source = ../../config/consul.d/client.json;
      };
    });

    # --- Secrets ---------------------------------

    age.secrets = {
      "consul.d/gossip.json" = {
        file = ../../secrets/consul.d/gossip.json.age;
        owner = "consul";
        group = "consul";
        mode = "644";
      };
      "consul.d/consul-agent-ca.pem" = {
        file = ../../secrets/consul.d/consul-agent-ca.pem.age;
        owner = "consul";
        group = "consul";
        mode = "644";
      };
    };

    # networking.firewall.allowedTCPPorts = [ 22 ];
  };
}
