// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.dto.jsonschema;

import static org.apache.juneau.internal.StringUtils.*;

import java.net.*;
import java.net.URI;
import java.util.*;

import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.transform.*;

/**
 * Represents a top-level schema object bean in the JSON-Schema core specification.
 *
 * <ul class='seealso'>
 * 	<li class='jp'>{@doc package-summary.html#TOC org.apache.juneau.dto.jsonschema}
 * </ul>
 */
@Bean(typeName="schema",
	bpi="id,$schema,$ref, title,description,type,definitions,properties,"
		+ "patternProperties,dependencies,items,multipleOf,maximum,exclusiveMaximum,"
		+ "minimum,exclusiveMinimum,maxLength,minLength,pattern,additionalItems,"
		+ "maxItems,minItems,uniqueItems,maxProperties,minProperties,required,"
		+ "additionalProperties,enum,allOf,anyOf,oneOf,not"
)
public class JsonSchema {
	private String name;                                   // Property name.  Not serialized.
	private URI id;
	private URI schemaVersion;
	private String title;
	private String description;
	private JsonType typeJsonType;                         // JsonType representation of type
	private JsonTypeArray typeJsonTypeArray;               // JsonTypeArray representation of type
	private Map<String,JsonSchema> definitions;
	private Map<String,JsonSchema> properties;
	private Map<String,JsonSchema> patternProperties;
	private Map<String,JsonSchema> dependencies;
	private JsonSchema itemsSchema;                            // JsonSchema representation of items
	private JsonSchemaArray itemsSchemaArray;                  // JsonSchemaArray representation of items
	private Number multipleOf;
	private Number maximum;
	private Boolean exclusiveMaximum;
	private Number minimum;
	private Boolean exclusiveMinimum;
	private Integer maxLength;
	private Integer minLength;
	private String pattern;
	private Boolean additionalItemsBoolean;                // Boolean representation of additionalItems
	private JsonSchemaArray additionalItemsSchemaArray;        // JsonSchemaArray representation of additionalItems
	private Integer maxItems;
	private Integer minItems;
	private Boolean uniqueItems;
	private Integer maxProperties;
	private Integer minProperties;
	private List<String> required;
	private Boolean additionalPropertiesBoolean;           // Boolean representation of additionalProperties
	private JsonSchema additionalPropertiesSchema;             // JsonSchema representation of additionalProperties
	private List<String> _enum;
	private List<JsonSchema> allOf;
	private List<JsonSchema> anyOf;
	private List<JsonSchema> oneOf;
	private JsonSchema not;
	private URI ref;
	private JsonSchemaMap schemaMap;
	private JsonSchema master = this;

	/**
	 * Default constructor.
	 */
	public JsonSchema() {}


	//-----------------------------------------------------------------------------------------------------------------
	// Bean properties
	//-----------------------------------------------------------------------------------------------------------------

	/**
	 * Bean property getter:  <property>name</property>.
	 *
	 * @return The value of the <property>name</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	@BeanIgnore
	public String getName() {
		return name;
	}

	/**
	 * Bean property setter:  <property>name</property>.
	 *
	 * @param name The new value for the <property>name</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	@BeanIgnore
	public JsonSchema setName(String name) {
		this.name = name;
		return this;
	}

	/**
	 * Bean property getter:  <property>id</property>.
	 *
	 * @return The value of the <property>id</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public URI getId() {
		return id;
	}

	/**
	 * Bean property setter:  <property>id</property>.
	 *
	 * <p>
	 * The value can be of any of the following types: {@link URI}, {@link URL}, {@link String}.
	 * Strings must be valid URIs.
	 *
	 * <p>
	 * URIs defined by {@link UriResolver} can be used for values.
	 *
	 * @param id The new value for the <property>id</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setId(Object id) {
		this.id = toURI(id);
		return this;
	}

	/**
	 * Bean property getter:  <property>$schema</property>.
	 *
	 * @return The value of the <property>$schema</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	@Beanp("$schema")
	public URI getSchemaVersionUri() {
		return schemaVersion;
	}

	/**
	 * Bean property setter:  <property>$schema</property>.
	 *
	 * <p>
	 * The value can be of any of the following types: {@link URI}, {@link URL}, {@link String}.
	 * Strings must be valid URIs.
	 *
	 * <p>
	 * URIs defined by {@link UriResolver} can be used for values.
	 *
	 * @param schemaVersion The new value for the <property>schemaVersion</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	@Beanp("$schema")
	public JsonSchema setSchemaVersionUri(Object schemaVersion) {
		this.schemaVersion = toURI(schemaVersion);
		return this;
	}

	/**
	 * Bean property getter:  <property>title</property>.
	 *
	 * @return The value of the <property>title</property> property, or <jk>null</jk> if it is not set.
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * Bean property setter:  <property>title</property>.
	 *
	 * @param title The new value for the <property>title</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setTitle(String title) {
		this.title = title;
		return this;
	}

	/**
	 * Bean property getter:  <property>description</property>.
	 *
	 * @return The value of the <property>description</property> property, or <jk>null</jk> if it is not set.
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * Bean property setter:  <property>description</property>.
	 *
	 * @param description The new value for the <property>description</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setDescription(String description) {
		this.description = description;
		return this;
	}

	/**
	 * Bean property getter:  <property>type</property>.
	 *
	 * @return
	 * 	The value of the <property>type</property> property on this bean, or <jk>null</jk> if it is not set.
	 * 	Can be either a {@link JsonType} or {@link JsonTypeArray} depending on what value was used to set it.
	 */
	@Swap(JsonTypeOrJsonTypeArraySwap.class)
	public Object getType() {
		if (typeJsonType != null)
			return typeJsonType;
		return typeJsonTypeArray;
	}

	/**
	 * Bean property getter:  <property>type</property>.
	 *
	 * <p>
	 * Convenience method for returning the <property>type</property> property when it is a {@link JsonType} value.
	 *
	 * @return
	 * 	The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonTypeArray}.
	 */
	@BeanIgnore
	public JsonType getTypeAsJsonType() {
		return typeJsonType;
	}

	/**
	 * Bean property getter:  <property>type</property>.
	 *
	 * <p>
	 * Convenience method for returning the <property>type</property> property when it is a {@link JsonTypeArray} value.
	 *
	 * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonType}.
	 */
	@BeanIgnore
	public JsonTypeArray getTypeAsJsonTypeArray() {
		return typeJsonTypeArray;
	}

	/**
	 * Bean property setter:  <property>type</property>.
	 *
	 * @param type
	 * 	The new value for the <property>type</property> property on this bean.
	 * 	This object must be of type {@link JsonType} or {@link JsonTypeArray}.
	 * @return This object (for method chaining).
	 * @throws BeanRuntimeException If invalid object type passed in.
	 */
	public JsonSchema setType(Object type) {
		this.typeJsonType = null;
		this.typeJsonTypeArray = null;
		if (type != null) {
			if (type instanceof JsonType)
				this.typeJsonType = (JsonType)type;
			else if (type instanceof JsonTypeArray)
				this.typeJsonTypeArray = (JsonTypeArray)type;
			else
				throw new BeanRuntimeException(JsonSchemaProperty.class,
					"Invalid attribute type ''{0}'' passed in.  Must be one of the following:  SimpleType, SimpleTypeArray",
					type.getClass().getName());
		}
		return this;
	}

	/**
	 * Bean property appender:  <property>type</property>.
	 *
	 * @param types The list of items to append to the <property>type</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addTypes(JsonType...types) {
		if (this.typeJsonTypeArray == null)
			this.typeJsonTypeArray = new JsonTypeArray();
		this.typeJsonTypeArray.addAll(types);
		return this;
	}

	/**
	 * Used during parsing to convert the <property>type</property> property to the correct class type.
	 *
	 * <ul class='spaced-list'>
	 * 	<li>
	 * 		If parsing a JSON-array, converts to a {@link JsonTypeArray}.
	 * 	<li>
	 * 		If parsing a JSON-object, converts to a {@link JsonType}.
	 * </ul>
	 *
	 * <p>
	 * Serialization method is a no-op.
	 */
	public static class JsonTypeOrJsonTypeArraySwap extends PojoSwap<Object,Object> {

		@Override /* PojoSwap */
		public Object swap(BeanSession session, Object o) throws SerializeException {
			return o;
		}

		@Override /* PojoSwap */
		public Object unswap(BeanSession session, Object o, ClassMeta<?> hint) throws ParseException {
			ClassMeta<?> cm = (
				o instanceof Collection
				? session.getClassMeta(JsonTypeArray.class)
				: session.getClassMeta(JsonType.class)
			);
			return session.convertToType(o, cm);
		}
	}

	/**
	 * Bean property getter:  <property>definitions</property>.
	 *
	 * @return
	 * 	The value of the <property>definitions</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Map<String,JsonSchema> getDefinitions() {
		return definitions;
	}

	/**
	 * Bean property setter:  <property>definitions</property>.
	 *
	 * @param definitions The new value for the <property>definitions</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setDefinitions(Map<String,JsonSchema> definitions) {
		this.definitions = definitions;
		if (definitions != null)
			setMasterOn(definitions.values());
		return this;
	}

	/**
	 * Bean property appender:  <property>definitions</property>.
	 *
	 * @param name The key in the definitions map entry.
	 * @param definition The value in the definitions map entry.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addDefinition(String name, JsonSchema definition) {
		if (this.definitions == null)
			this.definitions = new LinkedHashMap<>();
		this.definitions.put(name, definition);
		setMasterOn(definition);
		return this;
	}

	/**
	 * Bean property getter:  <property>properties</property>.
	 *
	 * @return The value of the <property>properties</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Map<String,JsonSchema> getProperties() {
		return properties;
	}

	/**
	 * Returns the property with the specified name.
	 *
	 * <p>
	 * This is equivalent to calling <property>getProperty(name, <jk>false</jk>)</property>.
	 *
	 * @param name The property name.
	 * @return The property with the specified name, or <jk>null</jk> if no property is specified.
	 */
	public JsonSchema getProperty(String name) {
		return getProperty(name, false);
	}

	/**
	 * Returns the property with the specified name.
	 *
	 * <p>
	 * If <property>resolve</property> is <jk>true</jk>, the property object will automatically be  resolved by calling
	 * {@link #resolve()}.
	 * Therefore, <property>getProperty(name, <jk>true</jk>)</property> is equivalent to calling
	 * <property>getProperty(name).resolve()</property>, except it's safe from a potential
	 * <property>NullPointerException</property>.
	 *
	 * @param name The property name.
	 * @param resolve If <jk>true</jk>, calls {@link #resolve()} on object before returning.
	 * @return The property with the specified name, or <jk>null</jk> if no property is specified.
	 */
	public JsonSchema getProperty(String name, boolean resolve) {
		if (properties == null)
			return null;
		JsonSchema s = properties.get(name);
		if (s == null)
			return null;
		if (resolve)
			s = s.resolve();
		return s;
	}

	/**
	 * Bean property setter:  <property>properties</property>.
	 *
	 * @param properties The new value for the <property>properties</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setProperties(Map<String,JsonSchema> properties) {
		this.properties = properties;
		if (properties != null)
			for (Map.Entry<String,JsonSchema> e : properties.entrySet()) {
				JsonSchema value = e.getValue();
				setMasterOn(value);
				value.setName(e.getKey());
			}
		return this;
	}

	/**
	 * Bean property appender:  <property>properties</property>.
	 *
	 * <p>
	 * Properties must have their <property>name</property> property set on them when using this method.
	 *
	 * @param properties The list of items to append to the <property>properties</property> property on this bean.
	 * @return This object (for method chaining).
	 * @throws BeanRuntimeException If property is found without a set <property>name</property> property.
	 */
	public JsonSchema addProperties(JsonSchema...properties) {
		if (this.properties == null)
			this.properties = new LinkedHashMap<>();
		for (JsonSchema p : properties) {
			if (p.getName() == null)
				throw new BeanRuntimeException(JsonSchema.class,
					"Invalid property passed to JsonSchema.addProperties().  Property name was null.");
			setMasterOn(p);
			this.properties.put(p.getName(), p);
		}
		return this;
	}

	/**
	 * Bean property getter:  <property>patternProperties</property>.
	 *
	 * @return
	 * 	The value of the <property>patternProperties</property> property on this bean, or <jk>null</jk> if it is
	 * 	not set.
	 */
	public Map<String,JsonSchema> getPatternProperties() {
		return patternProperties;
	}

	/**
	 * Bean property setter:  <property>patternProperties</property>.
	 *
	 * @param patternProperties The new value for the <property>patternProperties</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setPatternProperties(Map<String,JsonSchema> patternProperties) {
		this.patternProperties = patternProperties;
		if (patternProperties != null)
			for (Map.Entry<String,JsonSchema> e : patternProperties.entrySet()) {
				JsonSchema s = e.getValue();
				setMasterOn(s);
				s.setName(e.getKey());
			}
		return this;
	}

	/**
	 * Bean property appender:  <property>patternProperties</property>.
	 *
	 * <p>
	 * Properties must have their <property>name</property> property set to the pattern string when using this method.
	 *
	 * @param properties The list of items to append to the <property>patternProperties</property> property on this bean.
	 * @return This object (for method chaining).
	 * @throws BeanRuntimeException If property is found without a set <property>name</property> property.
	 */
	public JsonSchema addPatternProperties(JsonSchemaProperty...properties) {
		if (this.patternProperties == null)
			this.patternProperties = new LinkedHashMap<>();
		for (JsonSchema p : properties) {
			if (p.getName() == null)
				throw new BeanRuntimeException(JsonSchema.class,
					"Invalid property passed to JsonSchema.addProperties().  Property name was null.");
			setMasterOn(p);
			this.patternProperties.put(p.getName(), p);
		}
		return this;
	}

	/**
	 * Bean property getter:  <property>dependencies</property>.
	 *
	 * @return
	 * 	The value of the <property>dependencies</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Map<String,JsonSchema> getDependencies() {
		return dependencies;
	}

	/**
	 * Bean property setter:  <property>dependencies</property>.
	 *
	 * @param dependencies The new value for the <property>dependencies</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setDependencies(Map<String,JsonSchema> dependencies) {
		this.dependencies = dependencies;
		if (dependencies != null)
			setMasterOn(dependencies.values());
		return this;
	}

	/**
	 * Bean property appender:  <property>dependencies</property>.
	 *
	 * @param name The key of the entry in the dependencies map.
	 * @param dependency The value of the entry in the dependencies map.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addDependency(String name, JsonSchema dependency) {
		if (this.dependencies == null)
			this.dependencies = new LinkedHashMap<>();
		this.dependencies.put(name, dependency);
		setMasterOn(dependency);
		return this;
	}

	/**
	 * Bean property getter:  <property>items</property>.
	 *
	 * @return
	 * 	The value of the <property>items</property> property on this bean, or <jk>null</jk> if it is not set.
	 * 	Can be either a {@link JsonSchema} or {@link JsonSchemaArray} depending on what value was used to set it.
	 */
	@Swap(JsonSchemaOrSchemaArraySwap.class)
	public Object getItems() {
		if (itemsSchema != null)
			return itemsSchema;
		return itemsSchemaArray;
	}

	/**
	 * Bean property getter:  <property>items</property>.
	 *
	 * <p>
	 * Convenience method for returning the <property>items</property> property when it is a {@link JsonSchema} value.
	 *
	 * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonSchemaArray}.
	 */
	@BeanIgnore
	public JsonSchema getItemsAsSchema() {
		return itemsSchema;
	}

	/**
	 * Bean property getter:  <property>items</property>.
	 *
	 * <p>
	 * Convenience method for returning the <property>items</property> property when it is a {@link JsonSchemaArray} value.
	 *
	 * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonSchema}.
	 */
	@BeanIgnore
	public JsonSchemaArray getItemsAsSchemaArray() {
		return itemsSchemaArray;
	}

	/**
	 * Used during parsing to convert the <property>items</property> property to the correct class type.
	 *
	 * <ul class='spaced-list'>
	 * 	<li>
	 * 		If parsing a JSON-array, converts to a {@link JsonSchemaArray}.
	 * 	<li>
	 * 		If parsing a JSON-object, converts to a {@link JsonSchema}.
	 * </ul>
	 *
	 * <p>
	 * Serialization method is a no-op.
	 */
	public static class JsonSchemaOrSchemaArraySwap extends PojoSwap<Object,Object> {

		@Override /* PojoSwap */
		public Object swap(BeanSession session, Object o) throws SerializeException {
			return o;
		}

		@Override /* PojoSwap */
		public Object unswap(BeanSession session, Object o, ClassMeta<?> hint) throws ParseException {
			ClassMeta<?> cm = (
				o instanceof Collection
				? session.getClassMeta(JsonSchemaArray.class)
				: session.getClassMeta(JsonSchema.class)
			);
			return session.convertToType(o, cm);
		}
	}

	/**
	 * Bean property setter:  <property>items</property>.
	 *
	 * @param
	 * 	items The new value for the <property>items</property> property on this bean.
	 * 	This object must be of type {@link JsonSchema} or {@link JsonSchemaArray}.
	 * @return This object (for method chaining).
	 * @throws BeanRuntimeException If invalid object type passed in.
	 */
	public JsonSchema setItems(Object items) {
		this.itemsSchema = null;
		this.itemsSchemaArray = null;
		if (items != null) {
			if (items instanceof JsonSchema) {
				this.itemsSchema = (JsonSchema)items;
				setMasterOn(this.itemsSchema);
			} else if (items instanceof JsonSchemaArray) {
				this.itemsSchemaArray = (JsonSchemaArray)items;
				setMasterOn(this.itemsSchemaArray);
			} else
				throw new BeanRuntimeException(JsonSchemaProperty.class,
					"Invalid attribute type ''{0}'' passed in.  Must be one of the following:  JsonSchema, JsonSchemaArray",
					items.getClass().getName());
		}
		return this;
	}

	/**
	 * Bean property appender:  <property>items</property>.
	 *
	 * @param items The list of items to append to the <property>items</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addItems(JsonSchema...items) {
		if (this.itemsSchemaArray == null)
			this.itemsSchemaArray = new JsonSchemaArray();
		this.itemsSchemaArray.addAll(items);
		setMasterOn(items);
		return this;
	}

	/**
	 * Bean property getter:  <property>multipleOf</property>.
	 *
	 * @return The value of the <property>multipleOf</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Number getMultipleOf() {
		return multipleOf;
	}

	/**
	 * Bean property setter:  <property>multipleOf</property>.
	 *
	 * @param multipleOf The new value for the <property>multipleOf</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setMultipleOf(Number multipleOf) {
		this.multipleOf = multipleOf;
		return this;
	}

	/**
	 * Bean property getter:  <property>maximum</property>.
	 *
	 * @return The value of the <property>maximum</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Number getMaximum() {
		return maximum;
	}

	/**
	 * Bean property setter:  <property>maximum</property>.
	 *
	 * @param maximum The new value for the <property>maximum</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setMaximum(Number maximum) {
		this.maximum = maximum;
		return this;
	}

	/**
	 * Bean property getter:  <property>exclusiveMaximum</property>.
	 *
	 * @return
	 * 	The value of the <property>exclusiveMaximum</property> property on this bean, or <jk>null</jk> if it is
	 * 	not set.
	 */
	public Boolean isExclusiveMaximum() {
		return exclusiveMaximum;
	}

	/**
	 * Bean property setter:  <property>exclusiveMaximum</property>.
	 *
	 * @param exclusiveMaximum The new value for the <property>exclusiveMaximum</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setExclusiveMaximum(Boolean exclusiveMaximum) {
		this.exclusiveMaximum = exclusiveMaximum;
		return this;
	}

	/**
	 * Bean property getter:  <property>minimum</property>.
	 *
	 * @return The value of the <property>minimum</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Number getMinimum() {
		return minimum;
	}

	/**
	 * Bean property setter:  <property>minimum</property>.
	 *
	 * @param minimum The new value for the <property>minimum</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setMinimum(Number minimum) {
		this.minimum = minimum;
		return this;
	}

	/**
	 * Bean property getter:  <property>exclusiveMinimum</property>.
	 *
	 * @return
	 * 	The value of the <property>exclusiveMinimum</property> property on this bean, or <jk>null</jk> if it is
	 * 	not set.
	 */
	public Boolean isExclusiveMinimum() {
		return exclusiveMinimum;
	}

	/**
	 * Bean property setter:  <property>exclusiveMinimum</property>.
	 *
	 * @param exclusiveMinimum The new value for the <property>exclusiveMinimum</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setExclusiveMinimum(Boolean exclusiveMinimum) {
		this.exclusiveMinimum = exclusiveMinimum;
		return this;
	}

	/**
	 * Bean property getter:  <property>maxLength</property>.
	 *
	 * @return The value of the <property>maxLength</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Integer getMaxLength() {
		return maxLength;
	}

	/**
	 * Bean property setter:  <property>maxLength</property>.
	 *
	 * @param maxLength The new value for the <property>maxLength</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setMaxLength(Integer maxLength) {
		this.maxLength = maxLength;
		return this;
	}

	/**
	 * Bean property getter:  <property>minLength</property>.
	 *
	 * @return The value of the <property>minLength</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Integer getMinLength() {
		return minLength;
	}

	/**
	 * Bean property setter:  <property>minLength</property>.
	 *
	 * @param minLength The new value for the <property>minLength</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setMinLength(Integer minLength) {
		this.minLength = minLength;
		return this;
	}

	/**
	 * Bean property getter:  <property>pattern</property>.
	 *
	 * @return The value of the <property>pattern</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public String getPattern() {
		return pattern;
	}

	/**
	 * Bean property setter:  <property>pattern</property>.
	 *
	 * @param pattern The new value for the <property>pattern</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setPattern(String pattern) {
		this.pattern = pattern;
		return this;
	}

	/**
	 * Bean property getter:  <property>additionalItems</property>.
	 *
	 * @return
	 * 	The value of the <property>additionalItems</property> property on this bean, or <jk>null</jk> if it is
	 * 	not set.
	 * 	Can be either a {@link Boolean} or {@link JsonSchemaArray} depending on what value was used to set it.
	 */
	@Swap(BooleanOrSchemaArraySwap.class)
	public Object getAdditionalItems() {
		if (additionalItemsBoolean != null)
			return additionalItemsBoolean;
		return additionalItemsSchemaArray;
	}

	/**
	 * Bean property getter:  <property>additionalItems</property>.
	 *
	 * <p>
	 * Convenience method for returning the <property>additionalItems</property> property when it is a {@link Boolean}
	 * value.
	 *
	 * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonSchemaArray}.
	 */
	@BeanIgnore
	public Boolean getAdditionalItemsAsBoolean() {
		return additionalItemsBoolean;
	}

	/**
	 * Bean property getter:  <property>additionalItems</property>.
	 *
	 * <p>
	 * Convenience method for returning the <property>additionalItems</property> property when it is a
	 * {@link JsonSchemaArray} value.
	 *
	 * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link Boolean}.
	 */
	@BeanIgnore
	public List<JsonSchema> getAdditionalItemsAsSchemaArray() {
		return additionalItemsSchemaArray;
	}

	/**
	 * Bean property setter:  <property>additionalItems</property>.
	 *
	 * @param additionalItems
	 * 	The new value for the <property>additionalItems</property> property on this bean.
	 * 	This object must be of type {@link Boolean} or {@link JsonSchemaArray}.
	 * @return This object (for method chaining).
	 * @throws BeanRuntimeException If invalid object type passed in.
	 */
	public JsonSchema setAdditionalItems(Object additionalItems) {
		this.additionalItemsBoolean = null;
		this.additionalItemsSchemaArray = null;
		if (additionalItems != null) {
			if (additionalItems instanceof Boolean)
				this.additionalItemsBoolean = (Boolean)additionalItems;
			else if (additionalItems instanceof JsonSchemaArray) {
				this.additionalItemsSchemaArray = (JsonSchemaArray)additionalItems;
				setMasterOn(this.additionalItemsSchemaArray);
			} else
				throw new BeanRuntimeException(JsonSchemaProperty.class,
					"Invalid attribute type ''{0}'' passed in.  Must be one of the following:  Boolean, JsonSchemaArray",
					additionalItems.getClass().getName());
		}
		return this;
	}

	/**
	 * Bean property appender:  <property>additionalItems</property>.
	 *
	 * @param additionalItems
	 * 	The list of items to append to the <property>additionalItems</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addAdditionalItems(JsonSchema...additionalItems) {
		if (this.additionalItemsSchemaArray == null)
			this.additionalItemsSchemaArray = new JsonSchemaArray();
		this.additionalItemsSchemaArray.addAll(additionalItems);
		setMasterOn(additionalItems);
		return this;
	}

	/**
	 * Used during parsing to convert the <property>additionalItems</property> property to the correct class type.
	 *
	 * <ul class='spaced-list'>
	 * 	<li>
	 * 		If parsing a JSON-array, converts to a {@link JsonSchemaArray}.
	 * 	<li>
	 * 		If parsing a JSON-boolean, converts to a {@link Boolean}.
	 * </ul>
	 *
	 * <p>
	 * Serialization method is a no-op.
	 */
	public static class BooleanOrSchemaArraySwap extends PojoSwap<Object,Object> {

		@Override /* PojoSwap */
		public Object swap(BeanSession session, Object o) throws SerializeException {
			return o;
		}

		@Override /* PojoSwap */
		public Object unswap(BeanSession session, Object o, ClassMeta<?> hint) throws ParseException {
			ClassMeta<?> cm = (
				o instanceof Collection
				? session.getClassMeta(JsonSchemaArray.class)
				: session.getClassMeta(Boolean.class)
			);
			return session.convertToType(o, cm);
		}
	}

	/**
	 * Bean property getter:  <property>maxItems</property>.
	 *
	 * @return The value of the <property>maxItems</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Integer getMaxItems() {
		return maxItems;
	}

	/**
	 * Bean property setter:  <property>maxItems</property>.
	 *
	 * @param maxItems The new value for the <property>maxItems</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setMaxItems(Integer maxItems) {
		this.maxItems = maxItems;
		return this;
	}

	/**
	 * Bean property getter:  <property>minItems</property>.
	 *
	 * @return The value of the <property>minItems</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Integer getMinItems() {
		return minItems;
	}

	/**
	 * Bean property setter:  <property>minItems</property>.
	 *
	 * @param minItems The new value for the <property>minItems</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setMinItems(Integer minItems) {
		this.minItems = minItems;
		return this;
	}

	/**
	 * Bean property getter:  <property>uniqueItems</property>.
	 *
	 * @return
	 * 	The value of the <property>uniqueItems</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Boolean getUniqueItems() {
		return uniqueItems;
	}

	/**
	 * Bean property setter:  <property>uniqueItems</property>.
	 *
	 * @param uniqueItems The new value for the <property>uniqueItems</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setUniqueItems(Boolean uniqueItems) {
		this.uniqueItems = uniqueItems;
		return this;
	}

	/**
	 * Bean property getter:  <property>maxProperties</property>.
	 *
	 * @return
	 * 	The value of the <property>maxProperties</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Integer getMaxProperties() {
		return maxProperties;
	}

	/**
	 * Bean property setter:  <property>maxProperties</property>.
	 *
	 * @param maxProperties The new value for the <property>maxProperties</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setMaxProperties(Integer maxProperties) {
		this.maxProperties = maxProperties;
		return this;
	}

	/**
	 * Bean property getter:  <property>minProperties</property>.
	 *
	 * @return
	 * 	The value of the <property>minProperties</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public Integer getMinProperties() {
		return minProperties;
	}

	/**
	 * Bean property setter:  <property>minProperties</property>.
	 *
	 * @param minProperties The new value for the <property>minProperties</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setMinProperties(Integer minProperties) {
		this.minProperties = minProperties;
		return this;
	}

	/**
	 * Bean property getter:  <property>required</property>.
	 *
	 * @return The value of the <property>required</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public List<String> getRequired() {
		return required;
	}

	/**
	 * Bean property setter:  <property>required</property>.
	 *
	 * @param required The new value for the <property>required</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setRequired(List<String> required) {
		this.required = required;
		return this;
	}

	/**
	 * Bean property appender:  <property>required</property>.
	 *
	 * @param required The list of items to append to the <property>required</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addRequired(List<String> required) {
		if (this.required == null)
			this.required = new LinkedList<>();
		for (String r : required)
			this.required.add(r);
		return this;
	}

	/**
	 * Bean property appender:  <property>required</property>.
	 *
	 * @param required The list of items to append to the <property>required</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addRequired(String...required) {
		if (this.required == null)
			this.required = new LinkedList<>();
		for (String r : required)
			this.required.add(r);
		return this;
	}

	/**
	 * Bean property appender:  <property>required</property>.
	 *
	 * @param properties The list of items to append to the <property>required</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addRequired(JsonSchemaProperty...properties) {
		if (this.required == null)
			this.required = new LinkedList<>();
		for (JsonSchemaProperty p : properties)
			this.required.add(p.getName());
		return this;
	}

	/**
	 * Bean property getter:  <property>additionalProperties</property>.
	 *
	 * @return
	 * 	The value of the <property>additionalProperties</property> property on this bean, or <jk>null</jk> if it
	 * 	is not set.
	 * 	Can be either a {@link Boolean} or {@link JsonSchemaArray} depending on what value was used to set it.
	 */
	@Swap(BooleanOrSchemaSwap.class)
	public Object getAdditionalProperties() {
		if (additionalPropertiesBoolean != null)
			return additionalItemsBoolean;
		return additionalPropertiesSchema;
	}

	/**
	 * Bean property getter:  <property>additionalProperties</property>.
	 *
	 * <p>
	 * Convenience method for returning the <property>additionalProperties</property> property when it is a
	 * {@link Boolean} value.
	 *
	 * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link JsonSchema}.
	 */
	@BeanIgnore
	public Boolean getAdditionalPropertiesAsBoolean() {
		return additionalPropertiesBoolean;
	}

	/**
	 * Bean property getter:  <property>additionalProperties</property>.
	 *
	 * <p>
	 * Convenience method for returning the <property>additionalProperties</property> property when it is a
	 * {@link JsonSchema} value.
	 *
	 * @return The currently set value, or <jk>null</jk> if the property is not set, or is set as a {@link Boolean}.
	 */
	@BeanIgnore
	public JsonSchema getAdditionalPropertiesAsSchema() {
		return additionalPropertiesSchema;
	}

	/**
	 * Bean property setter:  <property>additionalProperties</property>.
	 *
	 * @param additionalProperties
	 * 	The new value for the <property>additionalProperties</property> property on this bean.
	 * 	This object must be of type {@link Boolean} or {@link JsonSchema}.
	 * @return This object (for method chaining).
	 * @throws BeanRuntimeException If invalid object type passed in.
	 */
	@Beanp(dictionary={JsonSchema.class})
	public JsonSchema setAdditionalProperties(Object additionalProperties) {
		this.additionalPropertiesBoolean = null;
		this.additionalPropertiesSchema = null;
		if (additionalProperties != null) {
			if (additionalProperties instanceof Boolean)
				this.additionalPropertiesBoolean = (Boolean)additionalProperties;
			else if (additionalProperties instanceof JsonSchema) {
				this.additionalPropertiesSchema = (JsonSchema)additionalProperties;
				setMasterOn(this.additionalPropertiesSchema);
			} else
				throw new BeanRuntimeException(JsonSchemaProperty.class,
					"Invalid attribute type ''{0}'' passed in.  Must be one of the following:  Boolean, JsonSchema",
					additionalProperties.getClass().getName());
		}
		return this;
	}

	/**
	 * Used during parsing to convert the <property>additionalProperties</property> property to the correct class type.
	 *
	 * <ul class='spaced-list'>
	 * 	<li>
	 * 		If parsing a JSON-object, converts to a {@link JsonSchema}.
	 * 	<li>
	 * 		If parsing a JSON-boolean, converts to a {@link Boolean}.
	 * </ul>
	 *
	 * <p>
	 * Serialization method is a no-op.
	 */
	public static class BooleanOrSchemaSwap extends PojoSwap<Object,Object> {

		@Override /* PojoSwap */
		public Object swap(BeanSession session, Object o) throws SerializeException {
			return o;
		}

		@Override /* PojoSwap */
		public Object unswap(BeanSession session, Object o, ClassMeta<?> hint) throws ParseException {
			ClassMeta<?> cm = (
				o instanceof Boolean
				? session.getClassMeta(Boolean.class)
				: session.getClassMeta(JsonSchema.class)
			);
			return session.convertToType(o, cm);
		}
	}

	/**
	 * Bean property getter:  <property>enum</property>.
	 *
	 * @return The value of the <property>enum</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public List<String> getEnum() {
		return _enum;
	}

	/**
	 * Bean property setter:  <property>enum</property>.
	 *
	 * @param _enum The new value for the <property>enum</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setEnum(List<String> _enum) {
		this._enum = _enum;
		return this;
	}

	/**
	 * Bean property appender:  <property>enum</property>.
	 *
	 * @param _enum The list of items to append to the <property>enum</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addEnum(String..._enum) {
		if (this._enum == null)
			this._enum = new LinkedList<>();
		for (String e : _enum)
			this._enum.add(e);
		return this;
	}

	/**
	 * Bean property getter:  <property>allOf</property>.
	 *
	 * @return The value of the <property>allOf</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public List<JsonSchema> getAllOf() {
		return allOf;
	}

	/**
	 * Bean property setter:  <property>allOf</property>.
	 *
	 * @param allOf The new value for the <property>allOf</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setAllOf(List<JsonSchema> allOf) {
		this.allOf = allOf;
		setMasterOn(allOf);
		return this;
	}

	/**
	 * Bean property appender:  <property>allOf</property>.
	 *
	 * @param allOf The list of items to append to the <property>allOf</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addAllOf(JsonSchema...allOf) {
		if (this.allOf == null)
			this.allOf = new LinkedList<>();
		setMasterOn(allOf);
		for (JsonSchema s : allOf)
			this.allOf.add(s);
		return this;
	}

	/**
	 * Bean property getter:  <property>anyOf</property>.
	 *
	 * @return The value of the <property>anyOf</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public List<JsonSchema> getAnyOf() {
		return anyOf;
	}

	/**
	 * Bean property setter:  <property>anyOf</property>.
	 *
	 * @param anyOf The new value of the <property>anyOf</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setAnyOf(List<JsonSchema> anyOf) {
		this.anyOf = anyOf;
		setMasterOn(anyOf);
		return this;
	}

	/**
	 * Bean property appender:  <property>anyOf</property>.
	 *
	 * @param anyOf The list of items to append to the <property>anyOf</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addAnyOf(JsonSchema...anyOf) {
		if (this.anyOf == null)
			this.anyOf = new LinkedList<>();
		setMasterOn(anyOf);
		for (JsonSchema s : anyOf)
			this.anyOf.add(s);
		return this;
	}

	/**
	 * Bean property getter:  <property>oneOf</property>.
	 *
	 * @return The value of the <property>oneOf</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public List<JsonSchema> getOneOf() {
		return oneOf;
	}

	/**
	 * Bean property setter:  <property>oneOf</property>.
	 *
	 * @param oneOf The new value for the <property>oneOf</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setOneOf(List<JsonSchema> oneOf) {
		this.oneOf = oneOf;
		setMasterOn(oneOf);
		return this;
	}

	/**
	 * Bean property appender:  <property>oneOf</property>.
	 *
	 * @param oneOf The list of items to append to the <property>oneOf</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema addOneOf(JsonSchema...oneOf) {
		if (this.oneOf == null)
			this.oneOf = new LinkedList<>();
		setMasterOn(oneOf);
		for (JsonSchema s : oneOf)
			this.oneOf.add(s);
		return this;
	}

	/**
	 * Bean property getter:  <property>not</property>.
	 *
	 * @return The value of the <property>not</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	public JsonSchema getNot() {
		return not;
	}

	/**
	 * Bean property setter:  <property>not</property>.
	 *
	 * @param not The new value for the <property>not</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setNot(JsonSchema not) {
		this.not = not;
		setMasterOn(not);
		return this;
	}

	/**
	 * Bean property getter:  <property>$ref</property>.
	 *
	 * @return The value of the <property>$ref</property> property on this bean, or <jk>null</jk> if it is not set.
	 */
	@Beanp("$ref")
	public URI getRef() {
		return ref;
	}

	/**
	 * Bean property setter:  <property>$ref</property>.
	 *
	 * <p>
	 * The value can be of any of the following types: {@link URI}, {@link URL}, {@link String}.
	 * Strings must be valid URIs.
	 *
	 * <p>
	 * URIs defined by {@link UriResolver} can be used for values.
	 *
	 * @param ref The new value for the <property>$ref</property> property on this bean.
	 * @return This object (for method chaining).
	 */
	@Beanp("$ref")
	public JsonSchema setRef(Object ref) {
		this.ref = toURI(ref);
		return this;
	}

	private void setMasterOn(JsonSchema s) {
		if (s != null)
			s.setMaster(this);
	}

	private void setMasterOn(JsonSchema[] ss) {
		if (ss != null)
			for (JsonSchema s : ss)
				setMasterOn(s);
	}

	private void setMasterOn(Collection<JsonSchema> ss) {
		if (ss != null)
			for (JsonSchema s : ss)
				setMasterOn(s);
	}

	private void setMasterOn(JsonSchemaArray ss) {
		if (ss != null)
			for (JsonSchema s : ss)
				setMasterOn(s);
	}

	/**
	 * Sets the master schema for this schema and all child schema objects.
	 *
	 * <p>
	 * All child elements in a schema should point to a single "master" schema in order to locate registered JsonSchemaMap
	 * objects for resolving external schemas.
	 *
	 * @param master The master schema to associate on this and all children.  Can be <jk>null</jk>.
	 */
	protected void setMaster(JsonSchema master) {
		this.master = master;
		if (definitions != null)
			for (JsonSchema s : definitions.values())
				s.setMaster(master);
		if (properties != null)
			for (JsonSchema s : properties.values())
				s.setMaster(master);
		if (patternProperties != null)
			for (JsonSchema s : patternProperties.values())
				s.setMaster(master);
		if (dependencies != null)
			for (JsonSchema s : dependencies.values())
				s.setMaster(master);
		if (itemsSchema != null)
			itemsSchema.setMaster(master);
		if (itemsSchemaArray != null)
			for (JsonSchema s : itemsSchemaArray)
				s.setMaster(master);
		if (additionalItemsSchemaArray != null)
			for (JsonSchema s : additionalItemsSchemaArray)
				s.setMaster(master);
		if (additionalPropertiesSchema != null)
			additionalPropertiesSchema.setMaster(master);
		if (allOf != null)
			for (JsonSchema s : allOf)
				s.setMaster(master);
		if (anyOf != null)
			for (JsonSchema s : anyOf)
				s.setMaster(master);
		if (oneOf != null)
			for (JsonSchema s : oneOf)
				s.setMaster(master);
		if (not != null)
			not.setMaster(master);
	}

	/**
	 * Resolve schema if reference.
	 *
	 * <p>
	 * If this schema is a reference to another schema (has its <property>$ref</property> property set), this
	 * method will retrieve the referenced schema from the schema map registered with this schema.
	 *
	 * <p>
	 * If this schema is not a reference, or no schema map is registered with this schema, this method is a no-op and
	 * simply returns this object.
	 *
	 * @return The referenced schema, or <jk>null</jk>.
	 */
	public JsonSchema resolve() {
		if (ref == null || master.schemaMap == null)
			return this;
		return master.schemaMap.get(ref);
	}

	/**
	 * Associates a schema map with this schema for resolving other schemas identified through <property>$ref</property>
	 * properties.
	 *
	 * @param schemaMap The schema map to associate with this schema.  Can be <jk>null</jk>.
	 * @return This object (for method chaining).
	 */
	public JsonSchema setSchemaMap(JsonSchemaMap schemaMap) {
		this.schemaMap = schemaMap;
		return this;
	}

	@Override /* Object */
	public String toString() {
		return JsonSerializer.DEFAULT.toString(this);
	}
}
