{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://github.com/mattbaconz/plugdev/blob/main/spec/plugdev.schema.json",
  "title": "PlugDev Configuration",
  "description": "Configuration schema for plugdev.yml",
  "type": "object",
  "oneOf": [
    { "$ref": "#/$defs/pluginConfig" },
    { "$ref": "#/$defs/modConfig" },
    { "$ref": "#/$defs/networkConfig" },
    { "$ref": "#/$defs/packConfig" },
    { "$ref": "#/$defs/discordBotConfig" }
  ],
  "$defs": {
    "devDefaults": {
      "type": "object",
      "properties": {
        "gamemode": {
          "type": "string",
          "enum": ["survival", "creative", "adventure", "spectator"],
          "default": "creative"
        },
        "world": {
          "type": "string",
          "enum": ["flat", "default", "void"],
          "default": "void"
        },
        "op": {
          "type": "boolean",
          "default": true,
          "description": "When true (default), PlugDev bootstrap auto-OPs every player on join."
        },
        "peaceful": { "type": "boolean", "default": true },
        "onlineMode": { "type": "boolean", "default": false },
        "applySkins": {
          "type": "boolean",
          "default": true,
          "description": "When true (default), bootstrap applies Mojang skins by username on the offline Paper loop."
        },
        "configEditor": {
          "type": "string",
          "enum": ["auto", "cursor", "code", "notepad", "system"],
          "default": "auto",
          "description": "Preferred editor for plugdev config open / TUI Config files (auto tries VISUAL, EDITOR, cursor, code, notepad, system)."
        }
      },
      "additionalProperties": false
    },
    "watchConfig": {
      "type": "object",
      "properties": {
        "paths": {
          "type": "array",
          "items": { "type": "string" },
          "default": ["src/"]
        },
        "configs": {
          "type": "array",
          "items": { "type": "string", "minLength": 1 },
          "default": ["config.yml"],
          "description": "Live plugin-data files that trigger reload, relative to plugins/<PluginName>/."
        },
        "debounceMs": { "type": "integer", "minimum": 100, "default": 500 },
        "reload": {
          "type": "object",
          "properties": {
            "java": {
              "type": "string",
              "enum": ["safe", "hotswap", "restart"],
              "description": "Plugin default: safe. hotswap = JDWP redefine for method bodies (falls back to safe). Mod: hotswap hint or restart."
            },
            "assets": {
              "type": "string",
              "enum": ["f3t", "restart", "none"],
              "default": "f3t"
            },
            "data": {
              "type": "string",
              "enum": ["reload", "restart", "none"],
              "default": "reload"
            }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "dependency": {
      "type": "object",
      "required": ["name"],
      "properties": {
        "name": { "type": "string" },
        "source": {
          "type": "string",
          "enum": ["hangar", "modrinth", "url"],
          "default": "hangar"
        },
        "author": { "type": "string", "description": "Hangar author (optional if preset alias)" },
        "slug": { "type": "string", "description": "Hangar slug or Modrinth project ID/slug" },
        "version": { "type": "string" },
        "url": { "type": "string" },
        "enabled": { "type": "boolean", "default": true }
      },
      "additionalProperties": false
    },
    "clientConfig": {
      "type": "object",
      "properties": {
        "launcher": {
          "type": "string",
          "enum": ["auto", "prism", "multimc", "embedded", "none"],
          "default": "auto"
        },
        "executable": {
          "type": "string",
          "description": "Path to prismlauncher.exe or MultiMC.exe when auto-detection fails"
        },
        "instance": {
          "type": "string",
          "description": "Prism/MultiMC instance folder name, e.g. plugdev-1.21.4"
        },
        "offline": {
          "type": "boolean",
          "default": false,
          "description": "When true, Prism/MultiMC uses --offline offlineName. Default false uses the signed-in Microsoft account."
        },
        "offlineName": {
          "type": "string",
          "default": "DevPlayer",
          "description": "Offline username when client.offline is true (also used by embedded client)"
        },
        "players": {
          "type": "array",
          "description": "Extra offline players to launch on plug run (in addition to offlineName). Each needs a distinct name. mode bot = headless Mineflayer (no GUI).",
          "items": {
            "type": "object",
            "properties": {
              "name": { "type": "string", "minLength": 1 },
              "mode": {
                "type": "string",
                "enum": ["client", "bot"],
                "default": "client",
                "description": "client = Minecraft window (embedded). bot = headless protocol alt (Mineflayer)."
              }
            },
            "required": ["name"],
            "additionalProperties": false
          }
        },
        "joinOnReady": {
          "type": "boolean",
          "default": true,
          "description": "Auto-join client when server ready (plugdev run)"
        }
      },
      "additionalProperties": false
    },
    "jvmConfig": {
      "type": "object",
      "properties": {
        "args": {
          "type": "array",
          "items": { "type": "string" }
        },
        "memory": { "type": "string", "default": "1G" },
        "enhancedRedefinition": { "type": "boolean", "default": false },
        "mixinAgent": {
          "type": "string",
          "enum": ["auto", "off"],
          "default": "auto"
        },
        "debugPort": { "type": "integer", "default": 5005 }
      },
      "additionalProperties": false
    },
    "runConfig": {
      "type": "object",
      "properties": {
        "cleanup": {
          "type": "string",
          "enum": ["never", "on-exit", "worlds"],
          "default": "never",
          "description": "never=keep .plugdev/run (fast restarts). on-exit=delete run dir on stop. worlds=wipe world folders each start/exit."
        },
        "autoStop": {
          "description": "Stop the Paper JVM when idle or the PlugDev CLI is gone. Duration like 1m, 30s, or false/off to disable. Default 1m.",
          "oneOf": [
            { "type": "boolean" },
            { "type": "string" },
            { "type": "integer", "minimum": 0 }
          ],
          "default": "1m"
        }
      },
      "additionalProperties": false
    },
    "updateConfig": {
      "type": "object",
      "properties": {
        "auto": {
          "type": "boolean",
          "default": false,
          "description": "When true, plugdev installs @plugdev/cli@latest after detecting an outdated version (also supported in ~/.plugdev/config.yml)."
        }
      },
      "additionalProperties": false
    },
    "integrationsConfig": {
      "type": "object",
      "properties": {
        "plugtrace": {
          "type": "object",
          "description": "Optional private PlugTrace dogfood: copy local JAR + write plugdev-identity.json",
          "properties": {
            "enabled": { "type": "boolean", "default": false },
            "jar": {
              "type": "string",
              "description": "Path to built PlugTrace fat JAR (relative to project or absolute). Not fetched from Hangar/Modrinth."
            },
            "artifact": {
              "type": "string",
              "enum": ["paper-modern", "folia", "auto"],
              "default": "auto",
              "description": "auto → paper-modern unless server is folia"
            }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "pluginConfig": {
      "type": "object",
      "required": ["type"],
      "properties": {
        "type": { "const": "plugin" },
        "server": {
          "type": "string",
          "enum": ["paper", "spigot", "folia", "purpur", "pufferfish"],
          "default": "paper"
        },
        "version": {
          "type": "string",
          "description": "Minecraft version, e.g. 1.21.4"
        },
        "port": { "type": "integer", "default": 25565 },
        "build": {
          "type": "object",
          "properties": {
            "system": { "type": "string", "enum": ["gradle", "maven"], "default": "gradle" },
            "task": { "type": "string", "default": "build" },
            "jarTask": { "type": "string", "default": "shadowJar" },
            "jarPattern": { "type": "string", "description": "Glob for built JAR, e.g. build/libs/*.jar or plugin-module/target/*.jar" },
            "module": {
              "type": "string",
              "description": "Maven reactor module for multi-module builds (passed as -pl <module> -am)"
            }
          },
          "additionalProperties": false
        },
        "dev": { "$ref": "#/$defs/devDefaults" },
        "watch": { "$ref": "#/$defs/watchConfig" },
        "deps": {
          "type": "array",
          "items": { "$ref": "#/$defs/dependency" }
        },
        "client": { "$ref": "#/$defs/clientConfig" },
        "jvm": { "$ref": "#/$defs/jvmConfig" },
        "run": { "$ref": "#/$defs/runConfig" },
        "update": { "$ref": "#/$defs/updateConfig" },
        "integrations": { "$ref": "#/$defs/integrationsConfig" }
      },
      "additionalProperties": false
    },
    "modConfig": {
      "type": "object",
      "required": ["type", "loader"],
      "properties": {
        "type": { "const": "mod" },
        "loader": {
          "type": "string",
          "enum": ["fabric", "quilt", "neoforge", "forge", "architectury"]
        },
        "version": { "type": "string" },
        "port": {
          "type": "integer",
          "default": 25565,
          "description": "Join port when using dedicated server mode (dev.mode: server)"
        },
        "dev": {
          "type": "object",
          "properties": {
            "mode": {
              "type": "string",
              "enum": ["client", "server", "datagen"],
              "default": "client"
            },
            "subproject": {
              "type": "string",
              "description": "Gradle subproject for multi-loader, e.g. :fabric. Omit for single-module Loom/MDG."
            },
            "gamemode": { "type": "string", "default": "creative" },
            "world": { "type": "string", "default": "flat" }
          },
          "additionalProperties": false
        },
        "watch": { "$ref": "#/$defs/watchConfig" },
        "client": { "$ref": "#/$defs/clientConfig" },
        "jvm": { "$ref": "#/$defs/jvmConfig" },
        "update": { "$ref": "#/$defs/updateConfig" }
      },
      "additionalProperties": false
    },
    "networkConfig": {
      "type": "object",
      "required": ["type"],
      "properties": {
        "type": { "const": "network" },
        "proxy": {
          "type": "object",
          "properties": {
            "software": { "type": "string", "enum": ["velocity", "waterfall"], "default": "velocity" },
            "port": { "type": "integer", "default": 25565 }
          },
          "additionalProperties": false
        },
        "backends": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": { "type": "string" },
              "software": { "type": "string", "default": "paper" },
              "version": { "type": "string" },
              "port": { "type": "integer" }
            },
            "required": ["name", "port"]
          }
        },
        "forwarding": {
          "type": "object",
          "properties": {
            "secret": { "type": "string" },
            "generate": { "type": "boolean", "default": true }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "packConfig": {
      "type": "object",
      "required": ["type"],
      "properties": {
        "type": { "const": "pack" },
        "packType": {
          "type": "string",
          "enum": ["datapack", "serverpack"],
          "default": "datapack"
        },
        "server": {
          "type": "object",
          "properties": {
            "software": { "type": "string", "default": "paper" },
            "version": { "type": "string" }
          },
          "additionalProperties": false
        },
        "watch": {
          "type": "object",
          "properties": {
            "paths": {
              "type": "array",
              "items": { "type": "string" },
              "default": ["data/"]
            },
            "reloadCommand": { "type": "string", "default": "reload" }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "discordBotConfig": {
      "type": "object",
      "required": ["type"],
      "properties": {
        "type": { "const": "discord-bot" },
        "bot": {
          "type": "object",
          "properties": {
            "runtime": {
              "type": "string",
              "enum": ["node"],
              "default": "node"
            },
            "entry": {
              "type": "string",
              "description": "auto | relative path | shell command (default: package.json scripts.dev / start / main)"
            },
            "tokenEnv": {
              "type": "string",
              "default": "DISCORD_TOKEN",
              "description": "Env var name for the bot token (value never logged)"
            }
          },
          "additionalProperties": false
        },
        "watch": { "$ref": "#/$defs/watchConfig" }
      },
      "additionalProperties": false
    }
  }
}
