// ***************************************************************************************************************************
// * 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.jsonschema;

import static org.apache.juneau.internal.ObjectUtils.*;
import static org.apache.juneau.jsonschema.TypeCategory.*;

import java.lang.reflect.*;
import java.util.*;
import java.util.regex.*;

import org.apache.juneau.*;
import org.apache.juneau.json.*;
import org.apache.juneau.jsonschema.annotation.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.transform.*;

/**
 * Session object that lives for the duration of a single use of {@link JsonSchemaSerializer}.
 *
 * <p>
 * This class is NOT thread safe.
 * It is typically discarded after one-time use although it can be reused within the same thread.
 */
public class JsonSchemaGeneratorSession extends BeanTraverseSession {

	private final JsonSchemaGenerator ctx;
	private final Map<String,ObjectMap> defs;
	private JsonSerializerSession jsSession;

	/**
	 * Create a new session using properties specified in the context.
	 *
	 * @param ctx
	 * 	The context creating this session object.
	 * 	The context contains all the configuration settings for this object.
	 * @param args
	 * 	Runtime arguments.
	 * 	These specify session-level information such as locale and URI context.
	 * 	It also include session-level properties that override the properties defined on the bean and
	 * 	serializer contexts.
	 */
	protected JsonSchemaGeneratorSession(JsonSchemaGenerator ctx, BeanSessionArgs args) {
		super(ctx, args);
		this.ctx = ctx;
		if (isUseBeanDefs())
			defs = new TreeMap<>();
		else
			defs = null;
	}

	/**
	 * Returns the JSON-schema for the specified object.
	 *
	 * @param o
	 * 	The object.
	 * 	<br>Can either be a POJO or a <code>Class</code>/<code>Type</code>.
	 * @return The schema for the type.
	 * @throws Exception
	 */
	public ObjectMap getSchema(Object o) throws Exception {
		return getSchema(toClassMeta(o), "root", null, false, false, null);
	}

	/**
	 * Returns the JSON-schema for the specified type.
	 *
	 * @param type The object type.
	 * @return The schema for the type.
	 * @throws Exception
	 */
	public ObjectMap getSchema(Type type) throws Exception {
		return getSchema(getClassMeta(type), "root", null, false, false, null);
	}

	/**
	 * Returns the JSON-schema for the specified type.
	 *
	 * @param cm The object type.
	 * @return The schema for the type.
	 * @throws Exception
	 */
	public ObjectMap getSchema(ClassMeta<?> cm) throws Exception {
		return getSchema(cm, "root", null, false, false, null);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private ObjectMap getSchema(ClassMeta<?> eType, String attrName, String[] pNames, boolean exampleAdded, boolean descriptionAdded, JsonSchemaBeanPropertyMeta jsbpm) throws Exception {

		if (ctx.isIgnoredType(eType))
			return null;

		ObjectMap out = new ObjectMap();

		if (eType == null)
			eType = object();

		ClassMeta<?> aType;			// The actual type (will be null if recursion occurs)
		ClassMeta<?> sType;			// The serialized type
		PojoSwap pojoSwap = eType.getPojoSwap(this);

		aType = push(attrName, eType, null);

		sType = eType.getSerializedClassMeta(this);

		String type = null, format = null;
		Object example = null, description = null;

		boolean useDef = isUseBeanDefs() && sType.isBean() && pNames == null;

		if (useDef) {
			exampleAdded = false;
			descriptionAdded = false;
		}

		if (useDef && defs.containsKey(getBeanDefId(sType))) {
			pop();
			return new ObjectMap().append("$ref", getBeanDefUri(sType));
		}

		ObjectMap ds = getDefaultSchemas().get(sType.getInnerClass().getName());
		if (ds != null && ds.containsKey("type")) {
			pop();
			return out.appendAll(ds);
		}

		JsonSchemaClassMeta jscm = null;
		if (pojoSwap != null && pojoSwap.getClass().getAnnotation(Schema.class) != null)
			jscm = getClassMeta(pojoSwap.getClass()).getExtendedMeta(JsonSchemaClassMeta.class);
		if (jscm == null)
			jscm = sType.getExtendedMeta(JsonSchemaClassMeta.class);

		TypeCategory tc = null;

		if (sType.isNumber()) {
			tc = NUMBER;
			if (sType.isDecimal()) {
				type = "number";
				if (sType.isFloat()) {
					format = "float";
				} else if (sType.isDouble()) {
					format = "double";
				}
			} else {
				type = "integer";
				if (sType.isShort()) {
					format = "int16";
				} else if (sType.isInteger()) {
					format = "int32";
				} else if (sType.isLong()) {
					format = "int64";
				}
			}
		} else if (sType.isBoolean()) {
			tc = BOOLEAN;
			type = "boolean";
		} else if (sType.isMap()) {
			tc = MAP;
			type = "object";
		} else if (sType.isBean()) {
			tc = BEAN;
			type = "object";
		} else if (sType.isCollection()) {
			tc = COLLECTION;
			type = "array";
		} else if (sType.isArray()) {
			tc = ARRAY;
			type = "array";
		} else if (sType.isEnum()) {
			tc = ENUM;
			type = "string";
		} else if (sType.isCharSequence() || sType.isChar()) {
			tc = STRING;
			type = "string";
		} else if (sType.isUri()) {
			tc = STRING;
			type = "string";
			format = "uri";
		} else {
			tc = STRING;
			type = "string";
		}

		// Add info from @Schema on bean property.
		if (jsbpm != null) {
			out.appendAll(jsbpm.getSchema());
		}

		out.appendAll(jscm.getSchema());

		out.appendIf(false, true, true, "type", type);
		out.appendIf(false, true, true, "format", format);

		if (aType != null) {

			example = getExample(sType, tc, exampleAdded);
			description = getDescription(sType, tc, descriptionAdded);
			exampleAdded |= example != null;
			descriptionAdded |= description != null;

			if (tc == BEAN) {
				ObjectMap properties = new ObjectMap();
				BeanMeta bm = getBeanMeta(sType.getInnerClass());
				if (pNames != null)
					bm = new BeanMetaFiltered(bm, pNames);
				for (Iterator<BeanPropertyMeta> i = bm.getPropertyMetas().iterator(); i.hasNext();) {
					BeanPropertyMeta p = i.next();
					if (p.canRead())
						properties.put(p.getName(), getSchema(p.getClassMeta(), p.getName(), p.getProperties(), exampleAdded, descriptionAdded, p.getExtendedMeta(JsonSchemaBeanPropertyMeta.class)));
				}
				out.put("properties", properties);

			} else if (tc == COLLECTION) {
				ClassMeta et = sType.getElementType();
				if (sType.isCollection() && sType.getInfo().isChildOf(Set.class))
					out.put("uniqueItems", true);
				out.put("items", getSchema(et, "items", pNames, exampleAdded, descriptionAdded, null));

			} else if (tc == ARRAY) {
				ClassMeta et = sType.getElementType();
				if (sType.isCollection() && sType.getInfo().isChildOf(Set.class))
					out.put("uniqueItems", true);
				out.put("items", getSchema(et, "items", pNames, exampleAdded, descriptionAdded, null));

			} else if (tc == ENUM) {
				out.put("enum", getEnums(sType));

			} else if (tc == MAP) {
				ObjectMap om = getSchema(sType.getValueType(), "additionalProperties", null, exampleAdded, descriptionAdded, null);
				if (! om.isEmpty())
					out.put("additionalProperties", om);

			}
		}

		out.appendAll(jscm.getSchema());

		out.appendIf(false, true, true, "description", description);
		out.appendIf(false, true, true, "x-example", example);

		if (ds != null)
			out.appendAll(ds);

		if (useDef) {
			defs.put(getBeanDefId(sType), out);
			out = new ObjectMap().append("$ref", getBeanDefUri(sType));
		}

		pop();

		return out;
	}

	private List<String> getEnums(ClassMeta<?> cm) {
		List<String> l = new ArrayList<>();
		for (Enum<?> e : getEnumConstants(cm.getInnerClass()))
			l.add(cm.toString(e));
		return l;
	}

	private Object getExample(ClassMeta<?> sType, TypeCategory t, boolean exampleAdded) throws Exception {
		boolean canAdd = isAllowNestedExamples() || ! exampleAdded;
		if (canAdd && (getAddExamplesTo().contains(t) || getAddExamplesTo().contains(ANY))) {
			Object example = sType.getExample(this);
			if (example != null)
				return JsonParser.DEFAULT.parse(toJson(example), Object.class);
		}
		return null;
	}

	private String toJson(Object o) throws SerializeException {
		if (jsSession == null)
			jsSession = ctx.getJsonSerializer().createSession(null);
		return jsSession.serializeToString(o);
	}

	private Object getDescription(ClassMeta<?> sType, TypeCategory t, boolean descriptionAdded) {
		boolean canAdd = isAllowNestedDescriptions() || ! descriptionAdded;
		if (canAdd && (getAddDescriptionsTo().contains(t) || getAddDescriptionsTo().contains(ANY)))
			return sType.toString();
		return null;
	}

	/**
	 * Returns the definition ID for the specified class.
	 *
	 * @param cm The class to get the definition ID of.
	 * @return The definition ID for the specified class.
	 */
	public String getBeanDefId(ClassMeta<?> cm) {
		return getBeanDefMapper().getId(cm);
	}

	/**
	 * Returns the definition URI for the specified class.
	 *
	 * @param cm The class to get the definition URI of.
	 * @return The definition URI for the specified class.
	 */
	public java.net.URI getBeanDefUri(ClassMeta<?> cm) {
		return getBeanDefMapper().getURI(cm);
	}

	/**
	 * Returns the definition URI for the specified class.
	 *
	 * @param id The definition ID to get the definition URI of.
	 * @return The definition URI for the specified class.
	 */
	public java.net.URI getBeanDefUri(String id) {
		return getBeanDefMapper().getURI(id);
	}

	/**
	 * Returns the definitions that were gathered during this session.
	 *
	 * <p>
	 * This map is modifiable and affects the map in the session.
	 *
	 * @return
	 * 	The definitions that were gathered during this session, or <jk>null</jk> if {@link JsonSchemaGenerator#JSONSCHEMA_useBeanDefs} was not enabled.
	 */
	public Map<String,ObjectMap> getBeanDefs() {
		return defs;
	}

	/**
	 * Adds a schema definition to this session.
	 *
	 * @param id The definition ID.
	 * @param def The definition schema.
	 * @return This object (for method chaining).
	 */
	public JsonSchemaGeneratorSession addBeanDef(String id, ObjectMap def) {
		if (defs != null)
			defs.put(id, def);
		return this;
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Properties
	//-----------------------------------------------------------------------------------------------------------------

	/**
	 * Configuration property:  Add descriptions to types.
	 *
	 * @see JsonSchemaGenerator#JSONSCHEMA_addDescriptionsTo
	 * @return
	 * 	Set of categories of types that descriptions should be automatically added to generated schemas.
	 */
	protected final Set<TypeCategory> getAddDescriptionsTo() {
		return ctx.getAddDescriptionsTo();
	}

	/**
	 * Configuration property:  Add examples.
	 *
	 * @see JsonSchemaGenerator#JSONSCHEMA_addExamplesTo
	 * @return
	 * 	Set of categories of types that examples should be automatically added to generated schemas.
	 */
	protected final Set<TypeCategory> getAddExamplesTo() {
		return ctx.getAddExamplesTo();
	}

	/**
	 * Configuration property:  Allow nested descriptions.
	 *
	 * @see JsonSchemaGenerator#JSONSCHEMA_allowNestedDescriptions
	 * @return
	 * 	<jk>true</jk> if nested descriptions are allowed in schema definitions.
	 */
	protected final boolean isAllowNestedDescriptions() {
		return ctx.isAllowNestedDescriptions();
	}

	/**
	 * Configuration property:  Allow nested examples.
	 *
	 * @see JsonSchemaGenerator#JSONSCHEMA_allowNestedExamples
	 * @return
	 * 	<jk>true</jk> if nested examples are allowed in schema definitions.
	 */
	protected final boolean isAllowNestedExamples() {
		return ctx.isAllowNestedExamples();
	}

	/**
	 * Configuration property:  Bean schema definition mapper.
	 *
	 * @see JsonSchemaGenerator#JSONSCHEMA_beanDefMapper
	 * @return
	 * 	Interface to use for converting Bean classes to definition IDs and URIs.
	 */
	protected final BeanDefMapper getBeanDefMapper() {
		return ctx.getBeanDefMapper();
	}

	/**
	 * Configuration property:  Default schemas.
	 *
	 * @see JsonSchemaGenerator#JSONSCHEMA_defaultSchemas
	 * @return
	 * 	Custom schema information for particular class types.
	 */
	protected final Map<String,ObjectMap> getDefaultSchemas() {
		return ctx.getDefaultSchemas();
	}

	/**
	 * Configuration property:  Ignore types from schema definitions.
	 *
	 * @see JsonSchemaGenerator#JSONSCHEMA_ignoreTypes
	 * @return
	 * 	Custom schema information for particular class types.
	 */
	protected final Set<Pattern> getIgnoreTypes() {
		return ctx.getIgnoreTypes();
	}

	/**
	 * Configuration property:  Use bean definitions.
	 *
	 * @see JsonSchemaGenerator#JSONSCHEMA_useBeanDefs
	 * @return
	 * 	<jk>true</jk> if schemas on beans will be serialized with <js>'$ref'</js> tags.
	 */
	protected final boolean isUseBeanDefs() {
		return ctx.isUseBeanDefs();
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Utility methods
	//-----------------------------------------------------------------------------------------------------------------

	private ClassMeta<?> toClassMeta(Object o) {
		if (o instanceof Type)
			return getClassMeta((Type)o);
		return getClassMetaForObject(o);
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Other methods
	//-----------------------------------------------------------------------------------------------------------------

	@Override /* Session */
	public ObjectMap asMap() {
		return super.asMap()
			.append("JsonSchemaGeneratorSession", new DefaultFilteringObjectMap()
			);
	}
}
