{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://needlescript.dev/language-reference.schema.json",
  "title": "NeedleScript language reference",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "version",
    "language",
    "generatedFiles",
    "preamble",
    "categories",
    "sections",
    "features",
    "standardLibrary"
  ],
  "properties": {
    "$schema": { "type": "string" },
    "version": { "type": "integer", "minimum": 1 },
    "language": { "const": "NeedleScript" },
    "generatedFiles": {
      "type": "object",
      "additionalProperties": false,
      "required": ["human", "llm", "featureData", "standardLibrary"],
      "properties": {
        "human": { "type": "string", "pattern": "\\.md$" },
        "llm": { "type": "string", "pattern": "\\.md$" },
        "featureData": { "type": "string", "pattern": "\\.generated\\.json$" },
        "standardLibrary": { "type": "string", "pattern": "\\.md$" }
      }
    },
    "preamble": { "type": "string", "minLength": 1 },
    "categories": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/category" }
    },
    "sections": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/section" }
    },
    "features": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/feature" }
    },
    "standardLibrary": {
      "$ref": "#/$defs/standardLibrary"
    }
  },
  "$defs": {
    "identifier": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9-]*$"
    },
    "moduleId": {
      "type": "string",
      "pattern": "^std\\.[a-z][a-z0-9_]*$"
    },
    "procedureId": {
      "type": "string",
      "pattern": "^std\\.[a-z][a-z0-9_]*\\.[a-z][a-z0-9_]*$"
    },
    "category": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "title", "description"],
      "properties": {
        "id": { "$ref": "#/$defs/identifier" },
        "title": { "type": "string", "minLength": 1 },
        "description": { "type": "string", "minLength": 1 }
      }
    },
    "section": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "title", "order", "tags", "humanMarkdown", "compactMarkdown"],
      "properties": {
        "id": { "$ref": "#/$defs/identifier" },
        "title": { "type": "string", "minLength": 1 },
        "order": { "type": "integer", "minimum": 1 },
        "tags": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": { "$ref": "#/$defs/identifier" }
        },
        "humanMarkdown": { "type": "string", "minLength": 1 },
        "compactMarkdown": { "type": "string", "minLength": 1 }
      }
    },
    "completion": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["kind", "text"],
          "properties": {
            "kind": { "const": "text" },
            "text": { "type": "string", "minLength": 1 }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["kind", "source", "quote"],
          "properties": {
            "kind": { "enum": ["modes", "mode-list"] },
            "source": { "$ref": "#/$defs/identifier" },
            "quote": { "enum": ["'", "\""] }
          }
        }
      ]
    },
    "editor": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kind", "detail", "documentation", "completion"],
      "properties": {
        "kind": { "enum": ["keyword", "function", "variable", "constant"] },
        "detail": { "type": "string", "minLength": 1 },
        "documentation": { "type": "string", "minLength": 1 },
        "example": { "type": "string", "minLength": 1 },
        "completion": { "$ref": "#/$defs/completion" },
        "isSnippet": { "const": true },
        "signatures": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "array",
            "items": { "type": "string" }
          }
        }
      }
    },
    "feature": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "label", "category", "tags", "summary", "editor"],
      "properties": {
        "id": { "$ref": "#/$defs/identifier" },
        "label": { "$ref": "#/$defs/identifier" },
        "category": { "$ref": "#/$defs/identifier" },
        "tags": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": { "$ref": "#/$defs/identifier" }
        },
        "aliases": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": { "$ref": "#/$defs/identifier" }
        },
        "aliasFor": { "$ref": "#/$defs/identifier" },
        "summary": { "type": "string", "minLength": 1 },
        "editor": { "$ref": "#/$defs/editor" }
      }
    },
    "standardLibraryGroup": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "title", "order", "tags", "procedureIds"],
      "properties": {
        "id": { "$ref": "#/$defs/identifier" },
        "title": { "type": "string", "minLength": 1 },
        "order": { "type": "integer", "minimum": 1 },
        "tags": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": { "$ref": "#/$defs/identifier" }
        },
        "procedureIds": {
          "type": "array",
          "uniqueItems": true,
          "items": { "$ref": "#/$defs/procedureId" }
        },
        "beforeMarkdown": { "type": "string", "minLength": 1 },
        "afterMarkdown": { "type": "string", "minLength": 1 }
      }
    },
    "standardLibraryModule": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "title",
        "order",
        "description",
        "purpose",
        "tags",
        "emitsStitches",
        "rngDraws",
        "groups"
      ],
      "properties": {
        "id": { "$ref": "#/$defs/moduleId" },
        "title": { "$ref": "#/$defs/moduleId" },
        "order": { "type": "integer", "minimum": 1 },
        "description": { "type": "string", "minLength": 1 },
        "purpose": { "type": "string", "minLength": 1 },
        "tags": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": { "$ref": "#/$defs/identifier" }
        },
        "emitsStitches": { "enum": ["never", "usually"] },
        "rngDraws": { "type": "string", "minLength": 1 },
        "groups": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/standardLibraryGroup" }
        }
      }
    },
    "standardLibraryProcedure": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "moduleId", "name", "params", "group", "tags", "summary", "documentation"],
      "properties": {
        "id": { "$ref": "#/$defs/procedureId" },
        "moduleId": { "$ref": "#/$defs/moduleId" },
        "name": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" },
        "params": { "type": "array", "items": { "type": "string" } },
        "group": { "$ref": "#/$defs/identifier" },
        "tags": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": { "$ref": "#/$defs/identifier" }
        },
        "summary": { "type": "string", "minLength": 1 },
        "documentation": { "type": "string", "minLength": 1 }
      }
    },
    "standardLibrary": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "preamble",
        "introductionTitle",
        "introductionMarkdown",
        "modules",
        "procedures",
        "footerMarkdown"
      ],
      "properties": {
        "preamble": { "type": "string", "minLength": 1 },
        "introductionTitle": { "type": "string", "minLength": 1 },
        "introductionMarkdown": { "type": "string", "minLength": 1 },
        "modules": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/standardLibraryModule" }
        },
        "procedures": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/standardLibraryProcedure" }
        },
        "footerMarkdown": { "type": "string", "minLength": 1 }
      }
    }
  }
}
