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

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import org.apache.flink.api.common.ExecutionConfig;
import org.apache.flink.api.common.functions.InvalidTypesException;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.typeinfo.TypeInfo;
import org.apache.flink.api.common.typeinfo.TypeInfoFactory;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.api.common.typeutils.TypeSerializer;
import org.apache.flink.api.java.tuple.Tuple1;
import org.apache.flink.api.java.tuple.Tuple2;
import org.junit.Test;

import static org.apache.flink.api.common.typeinfo.BasicTypeInfo.BOOLEAN_TYPE_INFO;
import static org.apache.flink.api.common.typeinfo.BasicTypeInfo.DOUBLE_TYPE_INFO;
import static org.apache.flink.api.common.typeinfo.BasicTypeInfo.FLOAT_TYPE_INFO;
import static org.apache.flink.api.common.typeinfo.BasicTypeInfo.INT_TYPE_INFO;
import static org.apache.flink.api.common.typeinfo.BasicTypeInfo.STRING_TYPE_INFO;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * Tests for extracting {@link org.apache.flink.api.common.typeinfo.TypeInformation} from types
 * using a {@link org.apache.flink.api.common.typeinfo.TypeInfoFactory}
 */
public class TypeInfoFactoryTest {

	@Test
	public void testSimpleType() {
		TypeInformation<?> ti = TypeExtractor.createTypeInfo(IntLike.class);
		assertEquals(INT_TYPE_INFO, ti);

		ti = TypeExtractor.getForClass(IntLike.class);
		assertEquals(INT_TYPE_INFO, ti);

		ti = TypeExtractor.getForObject(new IntLike());
		assertEquals(INT_TYPE_INFO, ti);
	}

	@Test
	public void testMyEitherGenericType() {
		MapFunction<Boolean, MyEither<Boolean, String>> f = new MyEitherMapper<>();
		TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(f, BOOLEAN_TYPE_INFO);
		assertTrue(ti instanceof EitherTypeInfo);
		EitherTypeInfo eti = (EitherTypeInfo) ti;
		assertEquals(BOOLEAN_TYPE_INFO, eti.getLeftType());
		assertEquals(STRING_TYPE_INFO, eti.getRightType());
	}

	@Test
	public void testMyOptionGenericType() {
		TypeInformation<MyOption<Tuple2<Boolean, String>>> inTypeInfo = new MyOptionTypeInfo<>(
			new TupleTypeInfo<Tuple2<Boolean, String>>(BOOLEAN_TYPE_INFO, STRING_TYPE_INFO));
		MapFunction<MyOption<Tuple2<Boolean, String>>, MyOption<Tuple2<Boolean, Boolean>>> f = new MyOptionMapper<>();
		TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(f, inTypeInfo);
		assertTrue(ti instanceof MyOptionTypeInfo);
		MyOptionTypeInfo oti = (MyOptionTypeInfo) ti;
		assertTrue(oti.getInnerType() instanceof TupleTypeInfo);
		TupleTypeInfo tti = (TupleTypeInfo) oti.getInnerType();
		assertEquals(BOOLEAN_TYPE_INFO, tti.getTypeAt(0));
		assertEquals(BOOLEAN_TYPE_INFO, tti.getTypeAt(1));
	}

	@Test
	public void testMyTuple() {
		TypeInformation<Tuple1<MyTuple<Double, String>>> inTypeInfo = new TupleTypeInfo<>(
			new MyTupleTypeInfo(DOUBLE_TYPE_INFO, STRING_TYPE_INFO));
		MapFunction<Tuple1<MyTuple<Double, String>>, Tuple1<MyTuple<Boolean, Double>>> f = new MyTupleMapperL2<>();
		TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(f, inTypeInfo);
		assertTrue(ti instanceof TupleTypeInfo);
		TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
		assertTrue(tti.getTypeAt(0) instanceof MyTupleTypeInfo);
		MyTupleTypeInfo mtti = (MyTupleTypeInfo) tti.getTypeAt(0);
		assertEquals(BOOLEAN_TYPE_INFO, mtti.getField0());
		assertEquals(DOUBLE_TYPE_INFO, mtti.getField1());
	}

	@Test
	public void testMyTupleHierarchy() {
		TypeInformation<?> ti = TypeExtractor.createTypeInfo(MyTuple2.class);
		assertTrue(ti instanceof MyTupleTypeInfo);
		MyTupleTypeInfo<?, ?> mtti = (MyTupleTypeInfo) ti;
		assertEquals(STRING_TYPE_INFO, mtti.getField0());
		assertEquals(BOOLEAN_TYPE_INFO, mtti.getField1());
	}

	@Test
	public void testMyTupleHierarchyWithInference() {
		TypeInformation<Tuple1<MyTuple3<Tuple1<Float>>>> inTypeInfo = new TupleTypeInfo<>(new MyTupleTypeInfo<>(
			new TupleTypeInfo<Tuple1<Float>>(FLOAT_TYPE_INFO), BOOLEAN_TYPE_INFO));
		MapFunction<Tuple1<MyTuple3<Tuple1<Float>>>, Tuple1<MyTuple3<Tuple2<Float, String>>>> f = new MyTuple3Mapper<>();
		TypeInformation ti = TypeExtractor.getMapReturnTypes(f, inTypeInfo);
		assertTrue(ti instanceof TupleTypeInfo);
		TupleTypeInfo<?> tti = (TupleTypeInfo) ti;
		assertTrue(tti.getTypeAt(0) instanceof MyTupleTypeInfo);
		MyTupleTypeInfo mtti = (MyTupleTypeInfo) tti.getTypeAt(0);
		assertEquals(new TupleTypeInfo<>(FLOAT_TYPE_INFO, STRING_TYPE_INFO), mtti.getField0());
		assertEquals(BOOLEAN_TYPE_INFO, mtti.getField1());
	}

	@Test(expected = InvalidTypesException.class)
	public void testMissingTypeInfo() {
		MapFunction f = new MyFaultyMapper();
		TypeExtractor.getMapReturnTypes(f, INT_TYPE_INFO);
	}

	@Test(expected = InvalidTypesException.class)
	public void testMissingTypeInference() {
		MapFunction f = new MyFaultyMapper2();
		TypeExtractor.getMapReturnTypes(f, new MyFaultyTypeInfo());
	}

	// --------------------------------------------------------------------------------------------
	//  Utilities
	// --------------------------------------------------------------------------------------------

	public static class MyTuple3Mapper<Y> implements MapFunction<Tuple1<MyTuple3<Tuple1<Y>>>, Tuple1<MyTuple3<Tuple2<Y, String>>>> {
		@Override
		public Tuple1<MyTuple3<Tuple2<Y, String>>> map(Tuple1<MyTuple3<Tuple1<Y>>> value) throws Exception {
			return null;
		}
	}

	public static class MyTuple3<T> extends MyTuple<T, Boolean> {
		// empty
	}

	public static class MyTuple2 extends MyTuple<String, Boolean> {
		// empty
	}

	public static class MyFaultyMapper2<T> implements MapFunction<MyFaulty<T>, MyFaulty<T>> {
		@Override
		public MyFaulty<T> map(MyFaulty<T> value) throws Exception {
			return null;
		}
	}

	public static class MyFaultyMapper<T> implements MapFunction<T, MyFaulty<T>> {
		@Override
		public MyFaulty<T> map(T value) throws Exception {
			return null;
		}
	}

	@TypeInfo(FaultyTypeInfoFactory.class)
	public static class MyFaulty<Y> {
		// empty
	}

	public static class FaultyTypeInfoFactory extends TypeInfoFactory {
		@Override
		public TypeInformation createTypeInfo(Type t, Map genericParameters) {
			return null;
		}
	}

	public static class MyFaultyTypeInfo extends TypeInformation<MyFaulty> {
		@Override
		public boolean isBasicType() {
			return false;
		}

		@Override
		public boolean isTupleType() {
			return false;
		}

		@Override
		public int getArity() {
			return 0;
		}

		@Override
		public int getTotalFields() {
			return 0;
		}

		@Override
		public Class<MyFaulty> getTypeClass() {
			return null;
		}

		@Override
		public boolean isKeyType() {
			return false;
		}

		@Override
		public TypeSerializer<MyFaulty> createSerializer(ExecutionConfig config) {
			return null;
		}

		@Override
		public String toString() {
			return null;
		}

		@Override
		public boolean equals(Object obj) {
			return false;
		}

		@Override
		public int hashCode() {
			return 0;
		}

		@Override
		public boolean canEqual(Object obj) {
			return false;
		}
	}

	public static class MyTupleMapperL1<A, B> implements MapFunction<Tuple1<MyTuple<A, String>>, Tuple1<MyTuple<B, A>>> {
		@Override
		public Tuple1<MyTuple<B, A>> map(Tuple1<MyTuple<A, String>> value) throws Exception {
			return null;
		}
	}

	public static class MyTupleMapperL2<C> extends MyTupleMapperL1<C, Boolean> {
		// empty
	}

	@TypeInfo(MyTupleTypeInfoFactory.class)
	public static class MyTuple<T0, T1> {
		// empty
	}

	public static class MyTupleTypeInfoFactory extends TypeInfoFactory<MyTuple> {
		@Override
		@SuppressWarnings("unchecked")
		public TypeInformation<MyTuple> createTypeInfo(Type t, Map<String, TypeInformation<?>> genericParameters) {
			return new MyTupleTypeInfo(genericParameters.get("T0"), genericParameters.get("T1"));
		}
	}

	public static class MyTupleTypeInfo<T0, T1> extends TypeInformation<MyTuple<T0, T1>> {
		private TypeInformation field0;
		private TypeInformation field1;

		public TypeInformation getField0() {
			return field0;
		}

		public TypeInformation getField1() {
			return field1;
		}

		public MyTupleTypeInfo(TypeInformation field0, TypeInformation field1) {
			this.field0 = field0;
			this.field1 = field1;
		}

		@Override
		public boolean isBasicType() {
			return false;
		}

		@Override
		public boolean isTupleType() {
			return false;
		}

		@Override
		public int getArity() {
			return 0;
		}

		@Override
		public int getTotalFields() {
			return 0;
		}

		@Override
		public Class<MyTuple<T0, T1>> getTypeClass() {
			return null;
		}

		@Override
		public boolean isKeyType() {
			return false;
		}

		@Override
		public TypeSerializer<MyTuple<T0, T1>> createSerializer(ExecutionConfig config) {
			return null;
		}

		@Override
		public String toString() {
			return null;
		}

		@Override
		public boolean equals(Object obj) {
			return false;
		}

		@Override
		public int hashCode() {
			return 0;
		}

		@Override
		public boolean canEqual(Object obj) {
			return false;
		}

		@Override
		public Map<String, TypeInformation<?>> getGenericParameters() {
			Map<String, TypeInformation<?>> map = new HashMap<>(2);
			map.put("T0", field0);
			map.put("T1", field1);
			return map;
		}
	}

	public static class MyOptionMapper<T> implements MapFunction<MyOption<Tuple2<T, String>>, MyOption<Tuple2<T, T>>> {
		@Override
		public MyOption<Tuple2<T, T>> map(MyOption<Tuple2<T, String>> value) throws Exception {
			return null;
		}
	}

	@TypeInfo(MyOptionTypeInfoFactory.class)
	public static class MyOption<T> {
		// empty
	}

	public static class MyOptionTypeInfoFactory<T> extends TypeInfoFactory<MyOption<T>> {
		@Override
		@SuppressWarnings("unchecked")
		public TypeInformation<MyOption<T>> createTypeInfo(Type t, Map<String, TypeInformation<?>> genericParams) {
			return new MyOptionTypeInfo(genericParams.get("T"));
		}
	}

	public static class MyOptionTypeInfo<T> extends TypeInformation<MyOption<T>> {

		private final TypeInformation<T> innerType;

		public MyOptionTypeInfo(TypeInformation<T> innerType) {
			this.innerType = innerType;
		}

		public TypeInformation<T> getInnerType() {
			return innerType;
		}

		@Override
		public boolean isBasicType() {
			return false;
		}

		@Override
		public boolean isTupleType() {
			return false;
		}

		@Override
		public int getArity() {
			return 0;
		}

		@Override
		public int getTotalFields() {
			return 1;
		}

		@Override
		public Class<MyOption<T>> getTypeClass() {
			return null;
		}

		@Override
		public boolean isKeyType() {
			return false;
		}

		@Override
		public TypeSerializer<MyOption<T>> createSerializer(ExecutionConfig config) {
			return null;
		}

		@Override
		public String toString() {
			return null;
		}

		@Override
		public boolean equals(Object obj) {
			return false;
		}

		@Override
		public int hashCode() {
			return 0;
		}

		@Override
		public boolean canEqual(Object obj) {
			return false;
		}

		@Override
		public Map<String, TypeInformation<?>> getGenericParameters() {
			Map<String, TypeInformation<?>> map = new HashMap<>(1);
			map.put("T", innerType);
			return map;
		}
	}

	public static class MyEitherMapper<T> implements MapFunction<T, MyEither<T, String>> {
		@Override
		public MyEither<T, String> map(T value) throws Exception {
			return null;
		}
	}

	@TypeInfo(MyEitherTypeInfoFactory.class)
	public static class MyEither<A, B> {
		// empty
	}

	public static class MyEitherTypeInfoFactory<A, B> extends TypeInfoFactory<MyEither<A, B>> {
		@Override
		@SuppressWarnings("unchecked")
		public TypeInformation<MyEither<A,B>> createTypeInfo(Type t, Map<String, TypeInformation<?>> genericParams) {
			return new EitherTypeInfo(genericParams.get("A"), genericParams.get("B"));
		}
	}

	@TypeInfo(IntLikeTypeInfoFactory.class)
	public static class IntLike {
		// empty
	}

	public static class IntLikeTypeInfoFactory extends TypeInfoFactory<IntLike> {
		@Override
		@SuppressWarnings("unchecked")
		public TypeInformation<IntLike> createTypeInfo(Type t, Map<String, TypeInformation<?>> genericParams) {
			return (TypeInformation) INT_TYPE_INFO;
		}
	}

}
