/*
 * 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.flink.api.common.typeinfo;

import org.apache.flink.annotation.Public;
import org.apache.flink.annotation.PublicEvolving;
import org.apache.flink.api.common.ExecutionConfig;
import org.apache.flink.api.common.functions.InvalidTypesException;
import org.apache.flink.api.common.typeutils.TypeSerializer;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.typeutils.TypeExtractor;
import org.apache.flink.util.FlinkRuntimeException;

import java.io.Serializable;
import java.util.Collections;
import java.util.Map;

/**
 * TypeInformation is the core class of Flink's type system. Flink requires a type information
 * for all types that are used as input or return type of a user function. This type information
 * class acts as the tool to generate serializers and comparators, and to perform semantic checks
 * such as whether the fields that are uses as join/grouping keys actually exist.
 *
 * <p>The type information also bridges between the programming languages object model and a
 * logical flat schema. It maps fields from the types to to columns (fields) in a flat schema.
 * Not all fields from a type are mapped to a separate fields in the flat schema and
 * often, entire types are mapped to one field. It is important to notice that the schema must
 * hold for all instances of a type. For that reason, elements in lists and arrays are not
 * assigned to individual fields, but the lists and arrays are considered to be one field in total,
 * to account for different lengths in the arrays.
 *
 * <ul>
 *   <li>Basic types are indivisible and are considered a single field.</li>
 *   <li>Arrays and collections are one field</li>
 *   <li>Tuples and case classes represent as many fields as the class has fields</li>
 * </ul>
 *
 * <p>To represent this properly, each type has an <i>arity</i> (the number of fields it contains
 * directly), and a <i>total number of fields</i> (number of fields in the entire schema of this
 * type, including nested types).
 *
 * <p>Consider the example below:
 * <pre>{@code
 * public class InnerType {
 *   public int id;
 *   public String text;
 * }
 *
 * public class OuterType {
 *   public long timestamp;
 *   public InnerType nestedType;
 * }
 * }</pre>
 *
 * <p>The types "id", "text", and "timestamp" are basic types that take up one field. The "InnerType"
 * has an arity of two, and also two fields totally. The "OuterType" has an arity of two fields,
 * and a total number of three fields ( it contains "id", "text", and "timestamp" through recursive flattening).
 *
 * @param <T> The type represented by this type information.
 */
@Public
public abstract class TypeInformation<T> implements Serializable {

	private static final long serialVersionUID = -7742311969684489493L;

	/**
	 * Checks if this type information represents a basic type.
	 * Basic types are defined in {@link BasicTypeInfo} and are primitives, their boxing types,
	 * Strings, Date, Void, ...
	 *
	 * @return True, if this type information describes a basic type, false otherwise.
	 */
	@PublicEvolving
	public abstract boolean isBasicType();

	/**
	 * Checks if this type information represents a Tuple type.
	 * Tuple types are subclasses of the Java API tuples.
	 *
	 * @return True, if this type information describes a tuple type, false otherwise.
	 */
	@PublicEvolving
	public abstract boolean isTupleType();

	/**
	 * Gets the arity of this type - the number of fields without nesting.
	 *
	 * @return Gets the number of fields in this type without nesting.
	 */
	@PublicEvolving
	public abstract int getArity();

	/**
	 * Gets the number of logical fields in this type. This includes its nested and transitively nested
	 * fields, in the case of composite types. In the example below, the OuterType type has three
	 * fields in total.
	 *
	 *
	 * @return The number of fields in this type, including its sub-fields (for composite types)
	 */
	@PublicEvolving
	public abstract int getTotalFields();

	/**
	 * Gets the class of the type represented by this type information.
	 *
	 * @return The class of the type represented by this type information.
	 */
	@PublicEvolving
	public abstract Class<T> getTypeClass();

	/**
	 * Optional method for giving Flink's type extraction system information about the mapping
	 * of a generic type parameter to the type information of a subtype. This information is necessary
	 * in cases where type information should be deduced from an input type.
	 *
	 * <p>For instance, a method for a {@link Tuple2} would look like this:
	 * <code>
	 * Map m = new HashMap();
	 * m.put("T0", this.getTypeAt(0));
	 * m.put("T1", this.getTypeAt(1));
	 * return m;
	 * </code>
	 *
	 * @return map of inferred subtypes; it does not have to contain all generic parameters as key;
	 *         values may be null if type could not be inferred
	 */
	@PublicEvolving
	public Map<String, TypeInformation<?>> getGenericParameters() {
		// return an empty map as the default implementation
		return Collections.emptyMap();
	}

	/**
	 * Checks whether this type can be used as a key. As a bare minimum, types have
	 * to be hashable and comparable to be keys.
	 *
	 * @return True, if the type can be used as a key, false otherwise.
	 */
	@PublicEvolving
	public abstract boolean isKeyType();

	/**
	 * Checks whether this type can be used as a key for sorting.
	 * The order produced by sorting this type must be meaningful.
	 */
	@PublicEvolving
	public boolean isSortKeyType() {
		return isKeyType();
	}

	/**
	 * Creates a serializer for the type. The serializer may use the ExecutionConfig
	 * for parameterization.
	 *
	 * @param config The config used to parameterize the serializer.
	 * @return A serializer for this type.
	 */
	@PublicEvolving
	public abstract TypeSerializer<T> createSerializer(ExecutionConfig config);

	@Override
	public abstract String toString();

	@Override
	public abstract boolean equals(Object obj);

	@Override
	public abstract int hashCode();

	/**
	 * Returns true if the given object can be equaled with this object. If not, it returns false.
	 *
	 * @param obj Object which wants to take part in the equality relation
	 * @return true if obj can be equaled with this, otherwise false
	 */
	public abstract boolean canEqual(Object obj);

	// ------------------------------------------------------------------------

	/**
	 * Creates a TypeInformation for the type described by the given class.
	 *
	 * <p>This method only works for non-generic types. For generic types, use the
	 * {@link #of(TypeHint)} method.
	 *
	 * @param typeClass The class of the type.
	 * @param <T> The generic type.
	 *
	 * @return The TypeInformation object for the type described by the hint.
	 */
	public static <T> TypeInformation<T> of(Class<T> typeClass) {
		try {
			return TypeExtractor.createTypeInfo(typeClass);
		}
		catch (InvalidTypesException e) {
			throw new FlinkRuntimeException(
					"Cannot extract TypeInformation from Class alone, because generic parameters are missing. " +
					"Please use TypeInformation.of(TypeHint) instead, or another equivalent method in the API that " +
					"accepts a TypeHint instead of a Class. " +
					"For example for a Tuple2<Long, String> pass a 'new TypeHint<Tuple2<Long, String>>(){}'.");
		}
	}

	/**
	 * Creates a TypeInformation for a generic type via a utility "type hint".
	 * This method can be used as follows:
	 * <pre>
	 * {@code
	 * TypeInformation<Tuple2<String, Long>> info = TypeInformation.of(new TypeHint<Tuple2<String, Long>>(){});
	 * }
	 * </pre>
	 *
	 * @param typeHint The hint for the generic type.
	 * @param <T> The generic type.
	 *
	 * @return The TypeInformation object for the type described by the hint.
	 */
	public static <T> TypeInformation<T> of(TypeHint<T> typeHint) {
		return typeHint.getTypeInfo();
	}
}
