// ***************************************************************************************************************************
// * 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.oapi;

import static org.apache.juneau.internal.StringUtils.*;
import static org.apache.juneau.httppart.HttpPartSchema.Type.*;
import static org.apache.juneau.httppart.HttpPartSchema.Format.*;
import static org.apache.juneau.httppart.HttpPartSchema.CollectionFormat.*;

import java.util.*;

import org.apache.juneau.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.uon.*;

/**
 * Session object that lives for the duration of a single use of {@link OpenApiParser}.
 *
 * <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 OpenApiParserSession extends UonParserSession {

	// Cache these for faster lookup
	private static final BeanContext BC = BeanContext.DEFAULT;
	private static final ClassMeta<Long> CM_Long = BC.getClassMeta(Long.class);
	private static final ClassMeta<Integer> CM_Integer = BC.getClassMeta(Integer.class);
	private static final ClassMeta<Double> CM_Double = BC.getClassMeta(Double.class);
	private static final ClassMeta<Float> CM_Float = BC.getClassMeta(Float.class);
	private static final ClassMeta<Boolean> CM_Boolean = BC.getClassMeta(Boolean.class);
	private static final ClassMeta<ObjectList> CM_ObjectList = BC.getClassMeta(ObjectList.class);
	private static final ClassMeta<ObjectMap> CM_ObjectMap = BC.getClassMeta(ObjectMap.class);

	private static final HttpPartSchema DEFAULT_SCHEMA = HttpPartSchema.DEFAULT;

	//-------------------------------------------------------------------------------------------------------------------
	// Instance
	//-------------------------------------------------------------------------------------------------------------------

	private final OpenApiParser ctx;

	/**
	 * 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 session arguments.
	 */
	protected OpenApiParserSession(OpenApiParser ctx, ParserSessionArgs args) {
		super(ctx, args);
		this.ctx = ctx;
	}


	@SuppressWarnings("unchecked")
	@Override /* HttpPartParser */
	public <T> T parse(HttpPartType partType, HttpPartSchema schema, String in, ClassMeta<T> type) throws ParseException, SchemaValidationException {
		boolean isOptional = type.isOptional();

		while (type != null && type.isOptional())
			type = (ClassMeta<T>)type.getElementType();

		if (type == null)
			type = (ClassMeta<T>)object();

		schema = ObjectUtils.firstNonNull(schema, getSchema(), DEFAULT_SCHEMA);

		T t = parseInner(partType, schema, in, type);
		if (t == null && type.isPrimitive())
			t = type.getPrimitiveDefault();
		schema.validateOutput(t, ctx);

		if (isOptional)
			t = (T)Optional.ofNullable(t);

		return t;
	}

	@SuppressWarnings({ "unchecked" })
	private<T> T parseInner(HttpPartType partType, HttpPartSchema schema, String in, ClassMeta<T> type) throws SchemaValidationException, ParseException {
		schema.validateInput(in);
		if (in == null) {
			if (schema.getDefault() == null)
				return null;
			in = schema.getDefault();
		} else {
			HttpPartSchema.Type t = schema.getType(type);
			HttpPartSchema.Format f = schema.getFormat(type);

			if (t == STRING) {
				if (type.isObject()) {
					if (f == BYTE)
						return (T)base64Decode(in);
					if (f == DATE || f == DATE_TIME)
						return (T)parseIsoCalendar(in);
					if (f == BINARY)
						return (T)fromHex(in);
					if (f == BINARY_SPACED)
						return (T)fromSpacedHex(in);
					if (f == HttpPartSchema.Format.UON)
						return super.parse(partType, schema, in, type);
					return (T)in;
				}
				if (f == BYTE)
					return toType(base64Decode(in), type);
				if (f == DATE || f == DATE_TIME)
					return toType(parseIsoCalendar(in), type);
				if (f == BINARY)
					return toType(fromHex(in), type);
				if (f == BINARY_SPACED)
					return toType(fromSpacedHex(in), type);
				if (f == HttpPartSchema.Format.UON)
					return super.parse(partType, schema, in, type);
				return toType(in, type);

			} else if (t == ARRAY) {
				if (type.isObject())
					type = (ClassMeta<T>)CM_ObjectList;

				ClassMeta<?> eType = type.isObject() ? string() : type.getElementType();
				if (eType == null)
					eType = schema.getParsedType().getElementType();

				HttpPartSchema.CollectionFormat cf = schema.getCollectionFormat();
				String[] ss = new String[0];

				if (cf == MULTI)
					ss = new String[]{in};
				else if (cf == CSV)
					ss = split(in, ',');
				else if (cf == PIPES)
					ss = split(in, '|');
				else if (cf == SSV)
					ss = splitQuoted(in);
				else if (cf == TSV)
					ss = split(in, '\t');
				else if (cf == HttpPartSchema.CollectionFormat.UON)
					return super.parse(partType, null, in, type);
				else if (cf == NO_COLLECTION_FORMAT) {
					if (firstNonWhitespaceChar(in) == '@' && lastNonWhitespaceChar(in) == ')')
						return super.parse(partType, null, in, type);
					ss = split(in, ',');
				}

				HttpPartSchema items = schema.getItems();
				if (items == null)
					items = HttpPartSchema.DEFAULT;
				Object[] o = new Object[ss.length];
				for (int i = 0; i < ss.length; i++)
					o[i] = parse(partType, items, ss[i], eType);
				if (type.hasMutaterFrom(schema.getParsedType()) || schema.getParsedType().hasMutaterTo(type))
					return toType(toType(o, schema.getParsedType()), type);
				return toType(o, type);

			} else if (t == BOOLEAN) {
				if (type.isObject())
					type = (ClassMeta<T>)CM_Boolean;
				if (type.isBoolean())
					return super.parse(partType, schema, in, type);
				return toType(super.parse(partType, schema, in, CM_Boolean), type);

			} else if (t == INTEGER) {
				if (type.isObject()) {
					if (f == INT64)
						type = (ClassMeta<T>)CM_Long;
					else
						type = (ClassMeta<T>)CM_Integer;
				}
				if (type.isNumber())
					return super.parse(partType, schema, in, type);
				return toType(super.parse(partType, schema, in, CM_Integer), type);

			} else if (t == NUMBER) {
				if (type.isObject()) {
					if (f == DOUBLE)
						type = (ClassMeta<T>)CM_Double;
					else
						type = (ClassMeta<T>)CM_Float;
				}
				if (type.isNumber())
					return super.parse(partType, schema, in, type);
				return toType(super.parse(partType, schema, in, CM_Integer), type);

			} else if (t == OBJECT) {
				if (type.isObject())
					type = (ClassMeta<T>)CM_ObjectMap;
				if (schema.hasProperties() && type.isMapOrBean()) {
					try {
						if (type.isBean()) {
							BeanMap<T> m = BC.createBeanSession().newBeanMap(type.getInnerClass());
							for (Map.Entry<String,Object> e : parse(partType, DEFAULT_SCHEMA, in, CM_ObjectMap).entrySet()) {
								String key = e.getKey();
								BeanPropertyMeta bpm = m.getPropertyMeta(key);
								m.put(key, parse(partType, schema.getProperty(key), stringify(e.getValue()), bpm == null ? object() : bpm.getClassMeta()));
							}
							return m.getBean();
						}
						Map<String,Object> m = (Map<String,Object>)type.newInstance();
						for (Map.Entry<String,Object> e : parse(partType, DEFAULT_SCHEMA, in, CM_ObjectMap).entrySet()) {
							String key = e.getKey();
							m.put(key, parse(partType, schema.getProperty(key), stringify(e.getValue()), object()));
						}
						return (T)m;
					} catch (Exception e1) {
						throw new ParseException(e1, "Could not instantiate type ''{0}''.", type);
					}
				}
				return super.parse(partType, schema, in, type);

			} else if (t == FILE) {
				throw new ParseException("File part not supported.");

			} else if (t == NO_TYPE) {
				// This should never be returned by HttpPartSchema.getType(ClassMeta).
				throw new ParseException("Invalid type.");
			}
		}

		return super.parse(partType, schema, in, type);
	}

	private <T> T toType(Object in, ClassMeta<T> type) throws ParseException {
		try {
			return convertToType(in, type);
		} catch (InvalidDataConversionException e) {
			throw new ParseException(e.getMessage());
		}
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Other methods
	//-----------------------------------------------------------------------------------------------------------------

	@Override /* Session */
	public ObjectMap toMap() {
		return super.toMap()
			.append("OpenApiParserSession", new DefaultFilteringObjectMap()
			);
	}
}
