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

let
  cfg = config.services.mcpo;

  configFile = pkgs.writeText "mcpo-config.json" (builtins.toJSON cfg.settings);

  inherit (lib)
    getExe
    mkEnableOption
    mkIf
    mkOption
    types
    ;
in
{
  options.services.mcpo = {
    enable = mkEnableOption "mcpo, an MCP-to-OpenAPI proxy server.";

    package = mkOption {
      type = types.nullOr types.package;
      description = "The package to use for mcpo. You have to specify this manually.";
      default = null;
    };

    port = mkOption {
      type = types.port;
      default = 8000;
      description = "Port on which the mcpo service should listen.";
    };

    user = mkOption {
      type = types.str;
      description = "The user the mcpo service will run as.";
      default = "mcpo";
    };

    group = mkOption {
      type = types.str;
      description = "The group the mcpo service will run as.";
      default = "mcpo";
    };

    workDir = mkOption {
      type = types.str;
      description = "The working directory for the mcpo service.";
      default = "/var/lib/mcpo";
    };

    settings = mkOption {
      type = types.attrs;
      description = "A set of attributes that will be translated into the JSON configuration file for mcpo. It follows the Claude Desktop format.";
      default = { };
      example = {
        mcpServers = {
          memory = {
            command = "npx";
            args = [
              "-y"
              "@modelcontextprotocol/server-memory"
            ];
          };
          time = {
            command = "uvx";
            args = [
              "mcp-server-time"
              "--local-timezone=America/New_York"
            ];
          };
          mcp_sse = {
            type = "sse";
            url = "http://127.0.0.1:8001/sse";
            headers = {
              Authorization = "Bearer token";
              X-Custom-Header = "value";
            };
          };
          mcp_streamable_http = {
            type = "streamable_http";
            url = "http://127.0.0.1:8002/mcp";
          };
        };
      };
    };
  };

  config = mkIf cfg.enable {
    systemd.tmpfiles.rules = [
      "d ${cfg.workDir} - ${cfg.user} ${cfg.group} - -"
    ];

    users.users."${cfg.user}" = {
      isSystemUser = true;
      group = cfg.group;
    };

    users.groups."${cfg.group}" = { };

    systemd.services.mcpo = {
      description = "Service for mcpo, an MCP-to-OpenAPI proxy server.";
      after = [ "network.target" ];
      wantedBy = [ "multi-user.target" ];
      serviceConfig = {
        ExecStart = "${getExe cfg.package} --port ${toString cfg.port} --config ${configFile}";
        Restart = "on-failure";
        User = cfg.user;
        Group = cfg.group;
        WorkingDirectory = cfg.workDir;
      };
    };
  };
}
