{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://tuffite.org/schema/v2/tuffite.schema.json",
  "title": "Tuffite application configuration v2",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "app",
    "build"
  ],
  "properties": {
    "$schema": {
      "type": "string"
    },
    "app": {
      "$ref": "#/$defs/app"
    },
    "build": {
      "$ref": "#/$defs/build"
    },
    "bundle": {
      "$ref": "#/$defs/bundle"
    },
    "productName": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128,
      "description": "Application display name and default bundle name. Defaults to the Cargo package name. Use a portable filename (up to 128 UTF-8 bytes); spaces and Unicode are supported."
    }
  },
  "$defs": {
    "stringArray": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "app": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "identifier",
        "security",
        "assets"
      ],
      "properties": {
        "identifier": {
          "type": "string",
          "minLength": 1
        },
        "security": {
          "$ref": "#/$defs/security"
        },
        "windows": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/window"
          }
        },
        "assets": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/assetRoute"
          }
        },
        "network": {
          "$ref": "#/$defs/network"
        },
        "utilities": {
          "type": "object",
          "propertyNames": {
            "maxLength": 128,
            "pattern": "^[A-Za-z_$][A-Za-z0-9_$]*$"
          },
          "additionalProperties": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "configuration": {
                "description": "Service-local JSON startup data (serialized limit 64 KiB); independent of session init."
              }
            }
          }
        }
      }
    },
    "security": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "csp": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4096,
          "pattern": "^[^\\r\\n]+$"
        },
        "capabilities": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/originCapability"
          }
        }
      },
      "required": [
        "capabilities"
      ]
    },
    "window": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "label",
        "url",
        "width",
        "height"
      ],
      "properties": {
        "label": {
          "type": "string",
          "minLength": 1
        },
        "url": {
          "type": "string",
          "minLength": 1
        },
        "title": {
          "type": "string"
        },
        "x": {
          "type": "integer"
        },
        "y": {
          "type": "integer"
        },
        "width": {
          "type": "integer",
          "minimum": 1,
          "maximum": 16384
        },
        "height": {
          "type": "integer",
          "minimum": 1,
          "maximum": 16384
        },
        "focused": {
          "type": "boolean"
        },
        "decorations": {
          "type": "boolean"
        },
        "minWidth": {
          "type": "integer",
          "minimum": 1,
          "maximum": 16384
        },
        "minHeight": {
          "type": "integer",
          "minimum": 1,
          "maximum": 16384
        },
        "maxWidth": {
          "type": "integer",
          "minimum": 1,
          "maximum": 16384
        },
        "maxHeight": {
          "type": "integer",
          "minimum": 1,
          "maximum": 16384
        }
      },
      "dependentRequired": {
        "x": [
          "y"
        ],
        "y": [
          "x"
        ]
      }
    },
    "build": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "devPackage": {
          "type": "string"
        },
        "devUrl": {
          "type": "string",
          "format": "uri"
        },
        "beforeDevCommand": {
          "oneOf": [
            {
              "type": "string"
            },
            {
              "type": "object"
            }
          ]
        },
        "beforeBuildCommand": {
          "oneOf": [
            {
              "type": "string"
            },
            {
              "type": "object"
            }
          ]
        },
        "devtoolsPort": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535
        },
        "profile": {
          "type": "string"
        },
        "shellApi": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "namespace",
            "definitions"
          ],
          "properties": {
            "namespace": {
              "type": "string",
              "pattern": "^[A-Za-z_$][A-Za-z0-9_$]*$"
            },
            "definitions": {
              "$ref": "#/$defs/stringArray"
            },
            "facade": {
              "enum": [
                "application",
                "framework"
              ]
            }
          }
        }
      },
      "required": [
        "shellApi"
      ]
    },
    "bundle": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "executable": {
          "type": "string"
        },
        "resources": {
          "$ref": "#/$defs/stringArray"
        },
        "icons": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "macos": {
              "type": "string",
              "description": "Project-relative .icns icon; defaults to Tuffite."
            },
            "windows": {
              "type": "string",
              "description": "Project-relative .ico icon; defaults to Tuffite."
            }
          }
        }
      }
    },
    "originCapability": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "identifier",
        "origins"
      ],
      "properties": {
        "identifier": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]+$"
        },
        "description": {
          "type": "string",
          "minLength": 1
        },
        "origins": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "minLength": 1
          },
          "uniqueItems": true
        },
        "shellApi": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/shellApiEntry"
          }
        },
        "explorer": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "create": {
              "type": "boolean"
            },
            "executeJavaScript": {
              "type": "boolean"
            }
          }
        }
      }
    },
    "network": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "disableHttp2": {
          "type": "boolean"
        },
        "maxResponseBytes": {
          "type": "integer",
          "minimum": 1,
          "maximum": 5242880
        },
        "timeoutSeconds": {
          "type": "integer",
          "minimum": 1,
          "maximum": 300
        }
      }
    },
    "assetRoute": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "origins",
        "paths"
      ],
      "oneOf": [
        {
          "required": [
            "file"
          ],
          "not": {
            "required": [
              "directory"
            ]
          }
        },
        {
          "required": [
            "directory"
          ],
          "not": {
            "required": [
              "file"
            ]
          }
        }
      ],
      "properties": {
        "origins": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "minLength": 1
          }
        },
        "paths": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "pattern": "^/"
          }
        },
        "file": {
          "type": "string",
          "minLength": 1
        },
        "directory": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "shellApiEntry": {
      "oneOf": [
        {
          "type": "string",
          "pattern": "^(?:\\*|(?:[A-Za-z_$][A-Za-z0-9_$]*\\.)+(?:[A-Za-z_$][A-Za-z0-9_$]*|\\*))$"
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "method"
          ],
          "properties": {
            "method": {
              "type": "string",
              "pattern": "^(?:\\*|(?:[A-Za-z_$][A-Za-z0-9_$]*\\.)+(?:[A-Za-z_$][A-Za-z0-9_$]*|\\*))$"
            },
            "allow": {
              "type": "array",
              "items": {}
            },
            "deny": {
              "type": "array",
              "items": {}
            }
          }
        }
      ]
    }
  }
}
