{
    "$schema":     "http://json-schema.org/draft-04/schema#",
    "title":       "Catalog",
    "description": "A puppet resource catalog",
    "type": "object",
    "properties": {
        "tags": {
            "description": "Tags: regex is from https://puppet.com/docs/puppet/latest/lang_reserved.html",
            "type": "array",
            "items": {
                "type": "string",
                "pattern": "\\A[[:alnum:]_][[:alnum:]_:.-]*\\Z"
            }
        },
        "name": {
            "type": "string"
        },
        "version": {
            "type": ["string", "integer"]
        },
        "code_id": {
            "type": ["string", "null"]
        },
        "catalog_uuid": {
            "type": "string"
        },
        "catalog_format": {
            "type": "integer"
        },
        "environment": {
            "type": "string"
        },
        "resources": {
            "description": "The array of resources in the catalog",
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                   "type": {
                       "type": "string"
                   },
                    "title": {
                        "type": "string"
                    },
                    "line": {
                        "type": "integer"
                    },
                    "file": {
                        "type": "string"
                    },
                    "exported": {
                        "type": "boolean"
                    },
                    "sensitive_parameters": {
                        "description": "An optional list of resource parameters to be treated as sensitive.",
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "tags": {
                        "description": "Tags: regex is from https://puppet.com/docs/puppet/latest/lang_reserved.html",
                        "type": "array",
                        "items": {
                            "type": "string",
                            "pattern": "\\A[[:alnum:]_][[:alnum:]_:.-]*\\Z"
                        }
                    },
                    "parameters": {
                        "description": "Parameters: regex is from https://puppet.com/docs/puppet/latest/lang_reserved.html",
                        "type": "object",
                        "patternProperties": {
                            "^[a-z][a-z0-9_]*$": {}
                        },
                        "additionalProperties": false
                    }
                },
                "required": ["type", "title", "tags", "exported"],
                "additionalProperties": false
            }
        },
        "edges": {
            "description": "An array of the containment relationships in the catalog.",
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "source": {
                        "description": "Containing object",
                        "type": "string"
                    },
                    "target": {
                        "description": "Contained object",
                        "type": "string"
                    }
                },
                "required": ["source", "target"],
                "additionalProperties": false
            }

        },
        "classes": {
            "type": "array",
            "items": {
                "type": "string"
            }
        },
        "metadata": {
            "description": "A mapping of non-recursive File resources to their required metadata",
            "type": "object",
            "patternProperties": {
                "^.+$": {
                    "$ref": "#/definitions/file_metadata"
                }
            }
        },
        "recursive_metadata": {
            "description": "A mapping of recursive File resources to a hash of sources and arrays of associated metadata for that resource",
            "type": "object",
            "patternProperties": {
                "^.+$": {
                    "type": "object",
                    "patternProperties": {
                        "^.+$": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/file_metadata"
                            }
                        }
                    }
                }
            }
        }
    },
    "required": ["tags", "name", "version", "code_id", "catalog_uuid", "catalog_format", "environment", "resources", "edges", "classes"],
    "additionalProperties": false,

    "definitions" : {
        "file_metadata": {
            "description": "Metadata about a file, directory, or symbolic link; as described in file_metadata.json",
            "type":        "object",
            "properties": {
                "path": {
                    "type": "string"
                },
                "relative_path": {
                    "oneOf": [{"type": "string"}, {"type": "null"}]
                },
                "links": {
                    "enum": ["manage", "follow"]
                },
                "owner": {
                    "type": "integer"
                },
                "group": {
                    "type": "integer"
                },
                "mode": {
                    "type": "integer"
                },
                "type": {
                    "enum": ["file", "directory", "link"]
                },
                "destination": {
                    "oneOf": [{"type": "string"}, {"type": "null"}]
                },
                "checksum": {
                    "type": "object",
                    "properties": {
                        "type": {
                            "enum": ["md5", "sha256", "ctime"]
                        },
                        "value": {
                            "type": "string"
                        }
                    },
                    "required": ["type", "value"],
                    "additionalProperties": false
                },
                "source": {
                    "type": "string"
                },
                "content_uri": {
                    "type": "string"
                }
            },
            "required": ["path", "relative_path", "links", "owner", "group", "mode", "type", "destination", "checksum"],
            "additionalProperties": false
        }
    }
}
