{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Config",
  "description": "A Warhol configuration object",
  "type": "object",
  "additionalProperties": false,
  "allOf": [
    { "$ref": "#/definitions/no-patternLib-url-requires-component-url" },
    { "$ref": "#/definitions/no-patternLib-url-requires-utils-url" },
    { "$ref": "#/definitions/no-patternLib-url-and-no-theme-url-requires-theme-subsection-url" }
  ],

  "definitions": {

    "no-patternLib-url-requires-component-url": {
      "if": {
        "required": [ "patternLibUrl" ],
        "properties": {
          "patternLibUrl": {
            "type": "string"
          }
        }
      },
      "then": {
        "properties": {
          "components": {
            "items": {
              "required": [ "source" ]
            }
          }
        }
      },
      "else": {
        "properties": {
          "components": {
            "items": {
              "required": [ "source", "componentUrl" ],
              "properties": {
                "componentUrl": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },

    "no-patternLib-url-requires-utils-url": {
      "if": {
        "required": [ "patternLibUrl" ],
        "properties": {
          "patternLibUrl": {
            "type": "string"
          }
        }
      },
      "else": {
        "properties": {
          "utils": {
            "required": [ "utilsUrl" ],
            "properties": {
              "utilsUrl": {
                "type": "string"
              }
            }
          }
        }
      }
    },

    "no-patternLib-url-and-no-theme-url-requires-theme-subsection-url": {
      "if": {
        "anyOf": [
          {
             "required": [ "patternLibUrl" ],
             "properties": {
               "patternLibUrl": {
                 "type": "string"
               }
             }
          },
          {
            "properties": {
              "theme": {
                "required": [ "themeUrl" ],
                "properties": {
                  "themeUrl": {
                    "type": "string"
                  }
                }
              }
            }
          }
        ]
      },
      "then": {
        "properties": {
          "theme": {
            "properties": {
              "colors": {
                "required": [ "sources" ]
              },
              "typography": {
                "required": [ "sources" ]
              },
              "icons": {
                "required": [ "sources" ]
              }
            }
          }
        }
      },
      "else": {
        "properties": {
          "theme": {
            "properties": {
              "colors": {
                "required": [ "sources", "colorsUrl" ],
                "properties": {
                  "colorsUrl": {
                    "type": "string"
                  }
                }
              },
              "typography": {
                "required": [ "sources", "typographyUrl" ],
                "properties": {
                  "typographyUrl": {
                    "type": "string"
                  }
                }
              },
              "icons": {
                "required": [ "sources", "iconsUrl" ],
                "properties": {
                  "iconsUrl": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    }
  },

  "properties": {
    "patternLibUrl": {
      "description": "The URL at which to find the pattern library's kitchen sink page",
      "type": [ "string", "null" ],
      "format": "uri"
    },
    "patternLibHeaders": {
      "description": "Headers to set when accessing the pattern library",
      "type": [ "object", "null" ],
      "additionalProperties": {
        "type": "string"
      }
    },
    "patternLibCookies": {
      "description": "Cookies to set when accessing the pattern library",
      "type": [ "array", "null" ],
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "domain": {
            "type": "string"
          },
          "expires": {
            "type": "integer"
          },
          "httpOnly": {
            "type": "boolean"
          },
          "secure": {
            "type": "boolean"
          },
          "sameSite": {
            "type": "string",
            "enum": [ "Strict", "Lax" ]
          }
        },
        "oneOf": [
          {
            "required": [ "name", "value", "url" ]
          },
          {
            "required": [ "name", "value", "domain" ]
          }
        ],
        "additionalProperties": false
      }
    },
    "breakpoints": {
      "description": "The screen widths with which to take snapshots",
      "type": [ "array", "null" ],
      "items": {
        "type": "integer",
        "minimum": 100
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "theme": {
      "description": "Theme invariants for the style guide like colors and font sizes",
      "type": [ "object", "null" ],
      "additionalProperties": false,
      "properties": {
        "themeUrl": {
          "description": "The URL to find the theme definitions on",
          "type": [ "string", "null" ],
          "format": "uri"
        },
        "colors": {
          "description": "Colors allowed in the style guide",
          "type": [ "object", "null" ],
          "additionalProperties": false,
          "properties": {
            "colorsUrl": {
              "description": "The URL to find the color definitions on",
              "type": [ "string", "null" ],
              "format": "uri"
            },
            "sources": {
              "description": "Selector for elements that define the allowed colors",
              "type": "string",
              "minLength": 1
            },
            "properties": {
              "description": "CSS properties to use as sources in the color sources elements",
              "type": "array",
              "items": {
                "type": "string",
                "enum": [ "background-color", "border-bottom-color", "border-left-color", "border-right-color", "border-top-color", "box-shadow", "color", "lighting-color", "outline-color", "text-decoration-color", "text-shadow" ]
              },
              "minItems": 1,
              "uniqueItems": true
            }
          }
        },
        "typography": {
          "description": "Typography examples for the style guide",
          "type": [ "object", "null" ],
          "additionalProperties": false,
          "properties": {
            "typographyUrl": {
              "description": "The URL to find the typography examples on",
              "type": [ "string", "null" ],
              "format": "uri"
            },
            "sources": {
              "description": "Selector for elements that contain typography examples",
              "type": "string",
              "minLength": 1
            },
            "properties": {
              "description": "CSS properties that define a typography example",
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "uniqueItems": true
            }
          }
        },
        "icons": {
          "description": "Icons",
          "type": [ "object", "null" ],
          "additionalProperties": false,
          "properties": {
            "iconsUrl": {
              "description": "The URL to find the icon examples on",
              "type": [ "string", "null" ],
              "format": "uri"
            },
            "type": {
              "description": "Indicates how the icons are implemented",
              "type": "string",
              "enum": [ "font" ]
            },
            "sources": {
              "description": "Selector for elements that serve as icon examples",
              "type": "string",
              "minLength": 1
            }
          }
        }
      }
    },
    "utils": {
      "description": "Style utilities",
      "type": [ "object", "null" ],
      "additionalProperties": false,
      "properties": {
        "utilsUrl": {
          "description": "The URL to find the utilities on",
          "type": [ "string", "null" ],
          "format": "uri"
        },
        "sources": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "type": {
                "description": "Whether to read declarations from an element or a css rule",
                "type": "string",
                "enum": [ "rule", "element" ]
              },
              "selector": {
                "description": "The selector for the rule or element from which to read the utility",
                "type": "string",
                "minLength": 1
              },
              "name": {
                "description": "A name for the utility",
                "type": "string",
                "minLength": 1
              },
              "components": {
                "type": "array",
                "items": {
                  "description": "Target selectors of components that the utility can apply to",
                  "type": "string",
                  "minLength": 1
                }
              }
            },
            "required": [ "type", "selector" ]
          },
          "uniqueItems": true
        }
      }
    },
    "components": {
      "description": "Component definitions",
      "type": [ "array", "null" ],
      "items": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "componentUrl": {
            "description": "The URL to find the component on, if different from the main component library url",
            "type": [ "string", "null" ],
            "format": "uri"
          },
          "name": {
            "description": "The name of the selected component",
            "type": "string",
            "minLength": 1
          },
          "source": {
            "description": "The selector used to find components in the component library or component url",
            "type": "string",
            "minLength": 1
          },
          "target": {
            "description": "The selector used to find component instances in the page, if different from the source selector",
            "type": "string",
            "minLength": 1
          }
        }
      },
      "uniqueItems": true
    }
  }
}
