{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://github.com/google/cyanobyte/spec/cyanobyte.schema.json",
  "title": "CyanoByte Specification Validator",
  "description": "This file is used to validate whether a given document meets the CyanoByte specification.",
  "type": "object",
  "properties": {
    "cyanobyte": {
      "description": "The version of the CyanoByte specification this file follows.",
      "type": "string"
    },
    "info": {
      "description": "Info block of the file",
      "type": "object",
      "properties": {
        "title": {
          "description": "The title of the document. This should be used as the class name in the auto-generated code and therefore should be short (e.g. the part name).",
          "type": "string"
        },
        "package": {
          "description": "Logical hierarchy of this device, typically organized as a reverse domain name.",
          "type": "string"
        },
        "description": {
          "description": "A description of the document.",
          "type": "string"
        },
        "contact": {
          "description": "Contact info for the maintainer.",
          "type": "object",
          "properties": {
            "name": {
              "description": "Name of the maintainer.",
              "type": "string"
            },
            "url": {
              "description": "URL of the maintainer organization.",
              "type": "string",
              "format": "uri"
            },
            "email": {
              "description": "Email address for the maintainer.",
              "type": "string",
              "format": "email"
            }
          },
          "required": [
            "name",
            "url",
            "email"
          ]
        },
        "copyright": {
          "description": "Copyright info for the source code.",
          "type": "object",
          "properties": {
            "name": {
              "description": "Name of the copyright holder.",
              "type": "string"
            },
            "date": {
              "description": "Year / years for the copyright.",
              "type": "string"
            }
          },
          "required": [
            "name",
            "date"
          ]
        },
        "license": {
          "description": "License this document uses. TODO: Add validation other than it being a string.",
          "type": "object",
          "properties": {
            "name": {
              "description": "A SPDX compliant license identifier",
              "anyOf": [
                {"type": "string"},
                {"enum": [
                  "Apache-2.0",
                  "MIT"
                ]}
              ]
            },
            "url": {
              "description": "If the license name is not SPDX compliant, this can link to the license",
              "type": "string"
            }
          },
          "required": [
            "name"
          ]
        },
        "version": {
          "description": "Version number for this document using kind of semver.",
          "type": "string"
        }
      },
      "required": [
        "title",
        "description",
        "contact",
        "license",
        "version"
      ]
    },
    "i2c": {
      "description": "I2C settings",
      "type": "object",
      "properties": {
        "addressType": {
          "description": "Addressing type of the component.",
          "type": "string",
          "enum": [
            "7-bit",
            "10-bit"
          ]
        },
        "address": {
          "description": "I2C Address of the component",
          "oneOf": [
            {"type": "integer"},
            {
              "type": "array",
              "items": {
                "description": "Array of potentially valid device addresses",
                "type": "integer"
              }
            }
          ]
        },
        "addressMask": {
          "description": "Address mask for addresses that can be altered",
          "type": "integer"
        },
        "endian": {
          "description": "Endianness of the component",
          "type": "string",
          "enum": [
            "little",
            "big"
          ]
        }
      },
      "required": [
        "addressType",
        "address",
        "addressMask"
      ]
    },
    "spi": {
      "description": "SPI settings",
      "type": "object",
      "properties": {
        "clockPolarity": {
          "description": "The value of the clock signal in an IDLE state",
          "type": "string",
          "enum": ["low", "high"],
          "default": "low"
        },
        "clockPhase": {
          "description": "On which clock edge is data transferred",
          "type": "string",
          "enum": ["leading", "trailing"],
          "default": "leading"
        },
        "frequency": {
          "description": "Maximum supported shared clock frequency in Hertz",
          "type": "number"
        },
        "endian": {
          "description": "Endianness of the component",
          "type": "string",
          "enum": [
            "little",
            "big"
          ],
          "default": "big"
        },
        "word": {
          "description": "The size of a word in bits",
          "type": "number",
          "default": 8
        },
        "address": {
          "description": "Device address. Required when spi.format is 'register'",
          "type": "number"
        },
        "format": {
          "description": "The data format for SPI payloads",
          "type": "string",
          "enum": [
            "register",
            "emboss"
          ]
        }
      },
      "required": [
        "frequency", "format"
      ]
    },
    "registers": {
      "description": "Chip registers",
      "type": "object",
      "items": {
        "description": "Outer object",
        "type": "object",
        "patternProperties": {
          "^.*$": {
            "description": "Chip register",
            "type": "object",
            "properties": {
              "title": {
                "description": "Title of the register",
                "type": "string"
              },
              "description": {
                "description": "Description of the register",
                "type": "string"
              },
              "address": {
                "description": "Address of the register",
                "type": "integer"
              },
              "length": {
                "description": "Length of the register in bits",
                "type": "integer"
              },
              "signed": {
                "description": "Whether the integer response should be signed when read",
                "type": "boolean"
              },
              "readWrite": {
                "description": "Can you read and/or write to this register",
                "type": "string",
                "enum": [
                  "R",
                  "R/W",
                  "W",
                  "n"
                ]
              }
            },
            "required": [
              "title",
              "description",
              "address",
              "length"
            ]
          }
        },
        "additionalProperties": false
      }
    },
    "fields": {
      "description": "Subcomponents of a register",
      "type": "object",
      "items": {
        "description": "Outer object",
        "type": "object",
        "patternProperties": {
          "^.*$": {
            "description": "Chip function",
            "type": "object",
            "properties": {
              "title": {
                "description": "Title of the function",
                "type": "string"
              },
              "description": {
                "description": "Description of the function",
                "type": "string"
              },
              "register": {
                "description": "Register of the function",
                "type": "string"
              },
              "readWrite": {
                "description": "Can you read and/or write to this register",
                "type": "string",
                "enum": [
                  "R",
                  "R/W",
                  "W",
                  "n"
                ]
              },
              "bitStart": {
                "description": "What is the starting bit?",
                "type": "integer"
              },
              "bitEnd": {
                "description": "What is the ending bit?",
                "type": "integer"
              },
              "type": {
                "description": "What type of value is this?",
                "type": "string",
                "enum": [
                  "enum",
                  "number"
                ]
              },
              "enum": {
                "description": "List of values",
                "type": "object",
                "items": {
                  "description": "Enum value",
                  "type": "object",
                  "properties": {
                    "title": {
                      "description": "Enum title",
                      "type": "string"
                    },
                    "value": {
                      "description": "Enum value",
                      "type": "integer"
                    }
                  }
                }
              }
            },
            "required": [
              "title",
              "description",
              "readWrite"
            ]
          }
        }
      }
    },
    "functions": {
      "description": "Chip functions",
      "type": "object",
      "items": {
        "description": "Outer object",
        "type": "object",
        "patternProperties": {
          "^.*$": {
            "description": "Chip function",
            "type": "object",
            "properties": {
              "title": {
                "description": "Title of the function",
                "type": "string"
              },
              "description": {
                "description": "Description of the function",
                "type": "string"
              },
              "register": {
                "description": "Register of the function",
                "type": "string"
              },
              "computed": {
                "description": "Properties for a computed element",
                "type": "object",
                "items": {
                  "description": "A computation",
                  "type": "object",
                  "patternProperties": {
                    "^.*$": {
                      "description": "Title of the computation",
                      "type": "object",
                      "properties": {
                        "variables": {
                          "description": "All variables used in the computation",
                          "type": "object",
                          "items": {
                            "description": "Variable name",
                            "type": "object",
                            "patternProperties": {
                              "^.$": {
                                "description": "Variable name",
                                "type": "string",
                                "enum": [
                                  "int8",
                                  "int16",
                                  "int32",
                                  "uint8",
                                  "uint16",
                                  "uint32"
                                ]
                              }
                            }
                          }
                        },
                        "logic": {
                          "description": "Set of logical operations",
                          "type": "array"
                        },
                        "return": {
                          "description": "The variable or variable array to return",
                          "type": ["string", "array"]
                        }
                      }
                    }
                  }
                }
              }
            },
            "required": [
              "title",
              "description"
            ]
          }
        }
      }
    },
    "extensions": {
      "description": "Reserved for custom parameters",
      "type": "object"
    }
  },
  "required": [
    "cyanobyte",
    "info"
  ]
}