{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "MapProxy Configuration",
  "description": "Configuration for a MapProxy server",
  "type": "object",
  "properties": {
    "layers": {
      "description": "The published layers",
      "type": "array",
      "items": {
        "$ref": "#/$defs/layer"
      }
    },
    "sources": {
      "title": "sources",
      "description": "The map data sources",
      "type": "object",
      "additionalProperties": {
        "$ref": "#/$defs/source"
      }
    },
    "services": {
      "title": "services",
      "description": "The available services and their configurations",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "wms": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "title": "wms",
              "description": "WMS service configuration",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "attribution": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "text": {
                      "type": "string"
                    }
                  }
                },
                "md": {
                  "title": "md",
                  "description": "The metadata config for the wms service",
                  "$ref": "#/$defs/metadata"
                },
                "inspire_md": {
                  "title": "md",
                  "description": "The inspire metadata config for the wms service",
                  "type": "object"
                },
                "srs": {
                  "title": "srs",
                  "description": "Supported SRS of the WMS service",
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "type": "string"
                  }
                },
                "bbox_srs": {
                  "title": "bbox_srs",
                  "description": "Supported SRS of the BBOX of the WMS service",
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "additionalProperties": false,
                        "required": ["srs", "bbox"],
                        "properties": {
                          "srs": {
                            "type": "string"
                          },
                          "bbox": {
                            "type": "array",
                            "minItems": 4,
                            "maxItems": 4,
                            "items": {
                              "type": "number"
                            }
                          }
                        }
                      }
                    ]
                  }
                },
                "image_formats": {
                  "title": "image_formats",
                  "description": "List of image mime types",
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "type": "string"
                  }
                },
                "featureinfo_types": {
                  "title": "featureinfo_types",
                  "description": "List of feature info types",
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "oneOf": [
                      {
                        "const": "text"
                      },
                      {
                        "const": "html"
                      },
                      {
                        "const": "xml"
                      },
                      {
                        "const": "json"
                      }
                    ]
                  }
                },
                "featureinfo_xslt": {
                  "description": "XSLT to transform feature info",
                  "oneOf": [
                    {
                      "type": "string"
                    },
                    {
                      "title": "featureinfo_xslt",
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "html": {
                          "type": "string"
                        },
                        "xml": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                },
                "strict": {
                  "description": "Require wms feature info request to contain all required parameters",
                  "type": "boolean"
                },
                "on_source_errors": {
                  "description": "What to do when one or more sources return errors or no response at all",
                  "oneOf": [
                    {
                      "const": "notify"
                    },
                    {
                      "const": "raise"
                    }
                  ]
                },
                "max_output_pixels": {
                  "description": "Maximum output size for a WMS requests in pixel",
                  "type": "array",
                  "minItems": 2,
                  "maxItems": 2,
                  "items": {
                    "type": "integer"
                  }
                },
                "versions": {
                  "description": "Versions the the MapProxy WMS should support",
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          ]
        },
        "tms": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "title": "tms",
              "description": "TMS service configuration",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "use_grid_names": {
                  "description": "Use name of grid instead of srs identifier in url",
                  "type": "boolean"
                },
                "origin": {
                  "description": "Change the default origin for the tiles",
                  "oneOf": [
                    {
                      "const": "nw"
                    },
                    {
                      "const": "sw"
                    }
                  ]
                }
              }
            }
          ]
        },
        "kml": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "title": "kml",
              "description": "KML service configuration",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "use_grid_names": {
                  "description": "Use name of grid instead of srs identifier in url",
                  "type": "boolean"
                }
              }
            }
          ]
        },
        "wmts": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "title": "wmts",
              "description": "WMTS service configuration",
              "type": "object",
              "properties": {
                "md": {
                  "title": "md",
                  "description": "The metadata config for the wmts service",
                  "$ref": "#/$defs/metadata"
                },
                "kvp": {
                  "title": "kvp",
                  "description": "Enable KVP requests",
                  "type": "boolean"
                },
                "restful": {
                  "title": "restful",
                  "description": "Enable restful requests",
                  "type": "boolean"
                },
                "restful_template": {
                  "title": "restful_template",
                  "description": "URL Template for restful tile request",
                  "type": "string"
                },
                "restful_fi_template": {
                  "title": "restful_fi_template",
                  "description": "URL Template for restful feature info request",
                  "type": "string"
                },
                "featureinfo_formats": {
                  "title": "featureinfo_formats",
                  "description": "List of feature info formats",
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "mimetype": {
                        "type": "string"
                      },
                      "suffix": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          ]
        },
        "demo": {
          "type": "null"
        },
        "ogcapi": {
          "description": "OGCAPI service configuration",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "enable_tiles": {
              "title": "enable_tiles",
              "description": "Whether to enable the OGC API Tiles service",
              "type": "boolean",
              "default": true
            },
            "enable_maps": {
              "title": "enable_tiles",
              "description": "Whether to enable the OGC API Maps service",
              "type": "boolean",
              "default": true
            },
            "map_srs": {
              "tile": "map_srs",
              "description": "Defines which SRS the OGC API Maps service supports.",
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "string"
              },
              "default": ["EPSG:4326", "EPSG:3857"]
            },
            "attribution": {
              "title": "attribution",
              "type": "object",
              "additionalProperties": false,
              "properties": {
                 "text": {
                    "title": "text",
                    "description": "Attribution text",
                    "type": "string"
                 }
              }
            },
            "md": {
              "title": "md",
              "description": "The metadata config for the OGCAPI service",
              "$ref": "#/$defs/ogcapi_metadata"
            },
            "default_dataset_layers": {
              "title": "default_dataset_layers",
              "description": "List of layer(s) that are used by default for dataset-wide /map and /map/tiles requests. If that option is not set, those endpoints are not available.",
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "string"
              }
            },
            "on_source_errors": {
              "description": "What to do when one or more sources return errors or no response at all",
              "oneOf": [
                {
                  "const": "notify"
                },
                {
                  "const": "raise"
                }
              ]
            },
            "max_output_pixels": {
              "description": "Maximum output size for a OGCAPI requests in pixel",
              "type": "array",
              "minItems": 2,
              "maxItems": 2,
              "items": {
                "type": "integer"
              }
            }
          }
        }
      }
    },
    "caches": {
      "title": "caches",
      "description": "The configured caches",
      "type": "object",
      "additionalProperties": {
        "$ref": "#/$defs/cache"
      }
    },
    "grids": {},

    "globals": {}
  },
  "required": ["layers", "services"],

  "$defs": {
    "layer": {
      "title": "layer",
      "description": "Configuration of a published layer",
      "type": "object",
      "additionalProperties": false,
      "anyOf": [
        {
          "required": ["sources"]
        },
        {
          "required": ["layers"]
        },
        {
          "required": ["tile_sources"]
        }
      ],
      "properties": {
        "name": {
          "description": "The addressable name of the layer",
          "oneOf": [
            {
              "type": "string"
            },
            {
              "type": "integer"
            }
          ]
        },
        "title": {
          "description": "The title of the layer",
          "type": "string"
        },
        "sources": {
          "description": "Associated sources for the layer",
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              }
            ]
          }
        },
        "layers": {
          "description": "Child layers of the layer",
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "item": {
            "$ref": "#/$defs/layer"
          }
        },
        "tile_sources": {
          "description": "Associated tile sources for the layer",
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "type": "string"
          }
        },
        "min_res": {
          "description": "Minimum resolution",
          "type": "number"
        },
        "max_res": {
          "description": "Maximum resolution",
          "type": "number"
        },
        "min_scale": {
          "description": "Minimum scale",
          "type": "number"
        },
        "max_scale": {
          "description": "Maximum scale",
          "type": "number"
        },
        "nominal_scale": {
          "description": "Nominal scale",
          "type": "number"
        },
        "legendurl": {
          "description": "URL to an image used as a legend for this layer",
          "type": "string"
        },
        "wmts_rest_legendurl": {
          "description": "A static legendurl for the wmts rest capabilites",
          "type": "string"
        },
        "wmts_kvp_legendurl": {
          "description": "A static legendurl for the wmts kvp capabilites",
          "type": "string"
        },
        "md": {
          "title": "md",
          "description": "Additional metadata for this layer",
          "type": "object"
        },
        "dimensions": {
          "title": "dimensions",
          "description": "Configure dimensions for the layer",
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "values": {
                "type": "array",
                "minItems": 1,
                "item": {
                  "oneOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "number"
                    }
                  ]
                }
              },
              "default": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "number"
                  }
                ]
              }
            }
          }
        }
      }
    },

    "cache": {
      "title": "cache",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "sources": {
          "description": "Sources of the cache",
          "oneOf": [
            {
              "type": "string"
            },
            {
              "type": "integer"
            },
            {
              "type": "array",
              "items": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "integer"
                  }
                ]
              }
            },
            {
              "title": "sources",
              "type": "object",
              "description": "Band merging config",
              "properties": {
                "r": {
                  "$ref": "#/$defs/bandMerge"
                },
                "g": {
                  "$ref": "#/$defs/bandMerge"
                },
                "b": {
                  "$ref": "#/$defs/bandMerge"
                },
                "l": {
                  "$ref": "#/$defs/bandMerge"
                }
              },
              "additionalProperties": false
            }
          ]
        },
        "format": {
          "description": "Internal image format",
          "type": "string"
        },
        "request_format": {
          "description": "Image format used in request",
          "type": "string"
        },
        "link_single_color_images": {
          "description": "How to store single color images",
          "oneOf": [
            {
              "const": true
            },
            {
              "const": "symlink"
            },
            {
              "const": "hardlink"
            }
          ]
        },
        "minimize_meta_requests": {
          "description": "Only issue a single request to the source",
          "type": "boolean"
        },
        "watermark": {
          "title": "watermark",
          "description": "Watermark for cached tiles",
          "type": "object",
          "additionalProperties": false,
          "required": ["text"],
          "properties": {
            "text": {
              "type": "string"
            },
            "opacity": {
              "type": "number"
            },
            "font_size": {
              "type": "number"
            },
            "color": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "minItems": 3,
                  "maxItems": 3,
                  "item": {
                    "type": "integer"
                  }
                }
              ]
            },
            "spacing": {
              "const": "wide"
            }
          }
        },
        "grids": {
          "description": "Grids used for storing by the cache",
          "type": "array",
          "item": {
            "type": "string"
          }
        },
        "meta_size": {
          "$ref": "#/$defs/metaSize"
        },
        "meta_buffer": {
          "$ref": "#/$defs/metaBuffer"
        },
        "bulk_meta_tiles": {
          "description": "Enables bulk loading of meta tiles",
          "type": "boolean"
        },
        "image": {
          "title": "image",
          "description": "Image options",
          "type": "object"
        },
        "use_direct_from_level": {
          "description": "Requests below this level will not be stored",
          "type": "integer"
        },
        "use_direct_from_res": {
          "description": "Requests below this resolution will not be stored",
          "type": "number"
        },
        "upscale_tiles": {
          "description": "Upscale tiles by this many zoom levels if not available in cache",
          "type": "integer"
        },
        "downscale_tiles": {
          "description": "Downscale tiles by this many zoom levels if not available in cache",
          "type": "integer"
        },
        "cache_rescaled_tiles": {
          "description": "Cache rescaled tiles",
          "type": "boolean"
        },
        "refresh_before": {
          "title": "refresh_before",
          "description": "Refresh tiles if requested before this time",
          "type": "object"
        },
        "disable_storage": {
          "description": "Do not use cache, get everything from source",
          "type": "boolean"
        },
        "cache_dir": {
          "description": "Directory to store data for this cache",
          "type": "string"
        },
        "cache": {
          "title": "cache",
          "description": "Configure type of the cache"
        }
      },
      "required": ["sources"]
    },

    "metaSize": {
      "description": "Size of meta tile in tiles",
      "type": "array",
      "minItems": 2,
      "maxItems": 2,
      "item": {
        "type": "integer"
      }
    },

    "metaBuffer": {
      "description": "Buffer around each meta tile",
      "type": "integer"
    },

    "source": {
      "title": "source",
      "type": "object",
      "properties": {
        "type": {
          "type": "string"
        },
        "layers": {},
        "req": {
          "title": "req",
          "type": "object",
          "properties": {
            "layers": {}
          }
        }
      },
      "required": ["type"],

      "if": {
        "properties": {
          "type": {
            "const": "wms"
          }
        }
      },
      "then": {
        "$ref": "#/$defs/source-wms"
      }
    },

    "source-wms": {
      "title": "source",
      "type": "object",
      "anyOf": [
        {
          "required": ["layers"]
        },
        {
          "properties": {
            "req": {
              "title": "req",
              "type": "object"
            },
            "wms_opts": {
              "title": "wms_opts",
              "type": "object",
              "properties": {
                "featureinfo": {
                  "type": "boolean"
                },
                "query_layers": {
                  "type": "string"
                }
              }
            }
          },          
          "required": ["req"]
        }
      ]
    },

    "metadata": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "title": {
          "type": "string"
        },
        "abstract": {
          "type": "string"
        },
        "online_resource": {
          "type": "string"
        },
        "contact": {
          "title": "contact",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "person": {
              "type": "string"
            },
            "position": {
              "type": "string"
            },
            "organization": {
              "type": "string"
            },
            "address": {
              "type": "string"
            },
            "city": {
              "type": "string"
            },
            "postcode": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "state": {
              "type": "string"
            },
            "country": {
              "type": "string"
            },
            "phone": {
              "type": "string"
            },
            "fax": {
              "type": "string"
            },
            "email": {
              "type": "string"
            }
          }
        },
        "access_constraints": {
          "type": "string"
        },
        "fees": {
          "type": "string"
        },
        "keyword_list": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "keywords"
            ],
            "properties": {
              "vocabulary": {
                "type": "string"
              },
              "keywords": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "metadata": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "url": {
                "type": "string"
              },
              "type": {
                "type": "string"
              },
              "format": {
                "type": "string"
              }
            },
            "required": ["url", "type", "format"]
          }
        }
      }
    },

    "bandMerge": {
      "description": "Band merging configs",
      "type": "array",
      "minItems": 1,
      "items": {
        "title": "sources",
        "type": "object",
        "properties": {
          "source": {
            "oneOf": [
              {
                "description": "A source name",
                "type": "string"
              },
              {
                "description": "A source name",
                "type": "integer"
              },
              {
                "description": "An array of source names",
                "type": "array",
                "minItems": 1,
                "items": {
                  "oneOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "integer"
                    }
                  ]
                }
              }
            ]
          },
          "band": {
            "description": "The band index starting from 0",
            "type": "integer"
          },
          "additionalProperties": false
        },
        "required": ["source", "band"]
      }
    },

    "ogcapi_metadata": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "identification": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
              "title": {
                  "type": "string"
              },
              "description": {
                  "type": "string"
              },
              "url": {
                  "type": "string"
              },
              "terms_of_service": {
                  "type": "string"
              },
              "keywords": {
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "type": "string"
                  }
              }
           }
        },
        "provider": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
              "name": {
                  "type": "string"
              },
              "url": {
                  "type": "string"
              }
          }
        },
        "contact": {
          "title": "contact",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string"
            },
            "email": {
              "type": "string"
            },
            "address": {
              "type": "string"
            },
            "city": {
              "type": "string"
            },
            "stateorprovince": {
              "type": "string"
            },
            "postalcode": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "country": {
              "type": "string"
            },
            "phone": {
              "type": "string"
            },
            "fax": {
              "type": "string"
            },
            "url": {
              "type": "string"
            },
            "instructions": {
              "type": "string"
            }
          }
        },
        "license": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
              "name": {
                  "type": "string"
              },
              "url": {
                  "type": "string"
              }
          }
        }
      }
    }

  }
}
