package com.banesco.common.domain.model;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class TypeBuilder {

    private TypeBuilder() {}

    public static Type listOf(Class<?> elementType) {
        return new ParameterizedType() {
            @Override
            public Type[] getActualTypeArguments() {
                return new Type[]{elementType};
            }

            @Override
            public Type getRawType() {
                return java.util.List.class;
            }

            @Override
            public Type getOwnerType() {
                return null;
            }
        };
    }

    public static Type parametricType(Class<?> rawType, Type... typeArguments) {
        return new ParameterizedType() {
            @Override
            public Type[] getActualTypeArguments() {
                return typeArguments;
            }

            @Override
            public Type getRawType() {
                return rawType;
            }

            @Override
            public Type getOwnerType() {
                return null;
            }
        };
    }

    public static Type apiPrivateResponseWithEither(Class<?> successType, Class<?> errorType) {
        Type eitherType = parametricType(Either.class, successType, errorType);
        return parametricType(ApiPrivateResponse.class, eitherType);
    }

    public static Type apiPrivateResponseWithListEither(Class<?> successType, Class<?> errorType) {
        Type listType = listOf(successType);
        Type eitherType = parametricType(Either.class, listType, errorType);
        return parametricType(ApiPrivateResponse.class, eitherType);
    }

    public static Type apiResponseType(Class<?> dataType) {
        return parametricType(ApiResponse.class, dataType);
    }

    public static Type apiResponseListType(Class<?> elementType) {
        Type listType = listOf(elementType);
        return parametricType(ApiResponse.class, listType);
    }
}