{
  config,
  pkgs,
  lib,
  inputs,
  ...
}:
with lib; let
  cfg = config.services.skynet_games_minecraft;

  # got tired of how long this is so I created a var for it.
  short_domain = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}";
in {
  imports = [
    ../acme.nix
    ../dns.nix
    ../firewall.nix
    ../nginx.nix
    inputs.arion.nixosModules.arion
  ];

  options.services.skynet_games_minecraft = {
    enable = mkEnableOption "Skynet Games Minecraft";

    host = {
      ip = mkOption {
        type = types.str;
      };

      name = mkOption {
        type = types.str;
      };
    };

    domain = {
      tld = mkOption {
        type = types.str;
        default = "ie";
      };

      base = mkOption {
        type = types.str;
        default = "skynet";
      };

      sub = mkOption {
        type = types.str;
        default = "minecraft.games";
      };
    };
  };

  config = mkIf cfg.enable {
    skynet_firewall.forward = [
      "ip daddr ${cfg.host.ip} tcp dport 80 counter packets 0 bytes 0 accept"
      "ip daddr ${cfg.host.ip} tcp dport 443 counter packets 0 bytes 0 accept"
      "ip daddr ${cfg.host.ip} tcp dport 25565 counter packets 0 bytes 0 accept"
    ];

    skynet_acme.domains = [
      "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"
      "*.${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"
    ];

    skynet_dns.records = [
      # the minecraft (web) config server
      {
        record = "config.${cfg.domain.sub}";
        r_type = "CNAME";
        value = cfg.host.name;
      }

      # our own minecraft hosts
      {
        record = "compsoc_classic.${cfg.domain.sub}";
        r_type = "CNAME";
        value = cfg.host.name;
      }
      {
        record = "compsoc.${cfg.domain.sub}";
        r_type = "CNAME";
        value = cfg.host.name;
      }

      # gsoc servers
      {
        record = "gsoc.${cfg.domain.sub}";
        r_type = "CNAME";
        value = cfg.host.name;
      }
      {
        record = "gsoc_abridged.${cfg.domain.sub}";
        r_type = "CNAME";
        value = cfg.host.name;
      }
    ];

    networking.firewall.allowedTCPPorts = [
      # for the proxy
      25565
    ];

    services.nginx.virtualHosts = {
      # https://config.minecraft.games.skynet.ie
      "config.${short_domain}" = {
        forceSSL = true;
        useACMEHost = "skynet";
        locations."/" = {
          proxyPass = "https://localhost:8443";
          proxyWebsockets = true;
        };
      };

      # https://compsoc_classic.minecraft.games.skynet.ie/map/
      "compsoc_classic.${short_domain}" = {
        forceSSL = true;
        useACMEHost = "skynet";
        locations."/map/".alias = "/etc/games/minecraft/craftycontrol/servers/f4c5eb33-c6d6-421c-81ab-ded31f6e8750/plugins/dynmap/web/";
      };
    };

    # arion is one way to use docker on nixos
    # see https://gitlab.com/c2842/computer_society/nixos/-/blob/733b867f4782afa795848135a83e97a5cafaf16a/applications/games/minecraft.nix
    # for an example of a single compose file with multiple services
    virtualisation.arion = {
      backend = "docker";
      projects = {
        minecraft.settings.services = {
          mc_proxy.service = {
            image = "itzg/mc-router:1.18.0";
            ports = ["25565:25565/tcp"];
            expose = ["25565"];
            command = [
              "--mapping=compsoc_classic.${short_domain}=mc_config:20000,compsoc.${short_domain}=mc_config:20001,gsoc.${short_domain}=mc_config:20002,gsoc.${short_domain}=mc_config:20002,gsoc_abridged.${short_domain}=mc_config:20003"
            ];
          };

          mc_config.service = {
            image = "registry.gitlab.com/crafty-controller/crafty-4:4.1.1";

            environment = {
              TZ = "Etc/UTC";
            };

            volumes = [
              "/etc/games/minecraft/craftycontrol/backups:/crafty/backups"
              "/etc/games/minecraft/craftycontrol/logs:/crafty/logs"
              "/etc/games/minecraft/craftycontrol/servers:/crafty/servers"
              "/etc/games/minecraft/craftycontrol/config:/crafty/app/config"
              "/etc/games/minecraft/craftycontrol/import:/crafty/import"
            ];

            ports = [
              # this ius https only
              "8443:8443/tcp"
              # compsoc classic
              "20000:20000/tcp"
              # compsoc
              "20001:20001/tcp"
              # games
              "20002:20002/tcp"
            ];
          };
        };
      };
    };
  };
}