/*
 * 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.geronimo.microprofile.openapi.impl.processor;

import org.apache.geronimo.microprofile.openapi.impl.model.DiscriminatorImpl;
import org.apache.geronimo.microprofile.openapi.impl.model.SchemaImpl;
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
import org.eclipse.microprofile.openapi.annotations.media.DiscriminatorMapping;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.models.Components;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonNumber;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonReaderFactory;
import javax.json.JsonString;
import javax.json.JsonValue;
import javax.json.bind.annotation.JsonbProperty;
import java.io.StringReader;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

import static java.beans.Introspector.decapitalize;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap;
import static java.util.Optional.of;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;

public class SchemaProcessor {
    private final Map<Type, org.eclipse.microprofile.openapi.models.media.Schema> cache = new HashMap<>();
    private final Map<Class<?>, String> providedRefs = new HashMap<>();
    private final Class<?> persistenceCapable;
    private final Class<?> responseType;
    private final JsonReaderFactory jsonReaderFactory;

    public SchemaProcessor() {
        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class<?> pc = null;
        try {
            pc = loader.loadClass("org.apache.openjpa.enhance.PersistenceCapable");
        } catch (final NoClassDefFoundError | ClassNotFoundException e) {
            // no-op
        }
        Class<?> responseType = null;
        try {
            responseType = loader.loadClass("javax.ws.rs.core.Response");
        } catch (final NoClassDefFoundError | ClassNotFoundException e) {
            // no-op
        }
        jsonReaderFactory = Json.createReaderFactory(emptyMap());
        persistenceCapable = pc;
        this.responseType = responseType;
    }

    public org.eclipse.microprofile.openapi.models.media.Schema mapSchemaFromClass(
            final Supplier<Components> components, final Type model) {
        final org.eclipse.microprofile.openapi.models.media.Schema cached = cache.get(model);
        if (cached != null) {
            return new SchemaImpl().type(cached.getType()).ref(toRef(Class.class.cast(model), null));
        }
        final SchemaImpl schema = new SchemaImpl();
        fillSchema(components, model, schema, null);
        return schema;
    }

    private String toRef(final Class<?> model, final String providedRef) {
        return "#/components/schemas/" + toRefName(model, providedRef);
    }

    // todo: introduce naming strategy? simplename can conflict so this is safer but ugly
    private String toRefName(final Class<?> model, final String providedRef) {
        return providedRefs.computeIfAbsent(
                model, k -> ofNullable(providedRef)
                        .orElseGet(() -> k.getName().replace('.', '_').replace('$', '_')));
    }

    public void fillSchema(
            final Supplier<org.eclipse.microprofile.openapi.models.Components>components,
            final Type rawModel,
            final org.eclipse.microprofile.openapi.models.media.Schema schema,
            final String providedRef) {
        final Type model = unwrapType(rawModel);
        if (Class.class.isInstance(model)) {
            if (boolean.class == model) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.BOOLEAN);
            } else if (Boolean.class == model) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.BOOLEAN).nullable(true);
            } else if (String.class == model || JsonString.class == model) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.STRING);
            } else if (double.class == model || float.class == model) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.NUMBER);
            } else if (Double.class == model || Float.class == model || JsonNumber.class == model) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.NUMBER).nullable(true);
            } else if (int.class == model || short.class == model || byte.class == model || long.class == model) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.INTEGER);
            } else if (Integer.class == model || Short.class == model || Byte.class == model || Long.class == model) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.INTEGER).nullable(true);
            } else if (Object.class == model || responseType == model || JsonObject.class == model || JsonValue.class == model) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.OBJECT)
                        .nullable(true)
                        .properties(new HashMap<>());
            } else if (BigDecimal.class == model || BigInteger.class == model) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.STRING).nullable(true);
            } else if (JsonArray.class == model) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.ARRAY)
                        .nullable(true)
                        .items(new SchemaImpl()
                                .type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.OBJECT)
                                .properties(new HashMap<>()));
            } else if (isStringable(model)) {
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.STRING).nullable(true);
            } else {
                final Class<?> from = Class.class.cast(model);
                if (from.isEnum()) {
                    schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.STRING)
                          .enumeration(asList(from.getEnumConstants()))
                          .nullable(true);
                } else if (from.isArray()) {
                    schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.ARRAY);
                    final SchemaImpl items = new SchemaImpl();
                    fillSchema(components, from.getComponentType(), items, null);
                    schema.items(items);
                } else if (Collection.class.isAssignableFrom(from)) {
                    schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.ARRAY);
                    final SchemaImpl items = new SchemaImpl();
                    fillSchema(components, Object.class, items, null);
                    schema.items(items);
                } else {
                    //if providedRef is null and the Schema name is not Empty, we set it as providedRef
                    final String ref = ofNullable(from.getAnnotation(Schema.class))
                            .filter(a -> !a.name().isEmpty())
                            .map(s -> {
                                final String sRef = s.name();
                                sets(components, s, schema, sRef);
                                return sRef;
                            })
                            .orElse(providedRef);

                    schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.OBJECT);

                    final org.eclipse.microprofile.openapi.models.media.Schema objectSchema = getOrCreateReusableObjectComponent(components, from, ref);
                    if (schema != objectSchema) {
                        schema.ref(toRef(from, ref));
                    }
                }
            }
        } else {
            schema.items(new SchemaImpl());
            if (ParameterizedType.class.isInstance(model)) {
                final ParameterizedType pt = ParameterizedType.class.cast(model);
                if (Class.class.isInstance(pt.getRawType()) && Map.class.isAssignableFrom(Class.class.cast(pt.getRawType()))) {
                    schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.OBJECT);
                } else if (pt.getActualTypeArguments().length == 1 && Class.class.isInstance(pt.getActualTypeArguments()[0])) {
                    schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.ARRAY);
                    final SchemaImpl items = new SchemaImpl();
                    fillSchema(components, Class.class.cast(pt.getActualTypeArguments()[0]), items, null);
                    schema.items(items);
                } else {
                    schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.ARRAY);
                }
            } else { // todo?
                schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.ARRAY);
            }
        }
    }

    /**
     * Creates or get from the cache the reusable object component
     *
     * @param components  components, where the schema will be added, if new created
     * @param from        the class for which we want create the schema
     * @param providedRef providedRef
     * @return the schema (from the cache or new created) for the given class
     */
    private org.eclipse.microprofile.openapi.models.media.Schema getOrCreateReusableObjectComponent(
        final Supplier<org.eclipse.microprofile.openapi.models.Components> components,
        final Class from,
        final String providedRef) {

        final org.eclipse.microprofile.openapi.models.media.Schema existingSchema = cache.get(from);
        if (existingSchema != null) {
            return existingSchema;
        }

        final SchemaImpl schema = new SchemaImpl();
        ofNullable(from.getAnnotation(Schema.class)).ifPresent(
            s -> sets(components, Schema.class.cast(s), schema, null));

        schema.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.OBJECT);

        if (cache.putIfAbsent(from, schema) == null) {
            components.get().addSchema(toRefName(from, providedRef), schema);
        }

        final Predicate<String> ignored = createIgnorePredicate(from);

        schema.properties(new HashMap<>());
        Class<?> current = from;
        while (current != null && current != Object.class) {
            Stream.of(current.getDeclaredFields())
                .filter(it -> isVisible(it, it.getModifiers()))
                .peek(f -> handleRequired(schema, f, () -> findFieldName(f)))
                .forEach(f -> {
                    final String fieldName = findFieldName(f);
                    if (!ignored.test(fieldName)) {
                        schema.getProperties().put(fieldName, mapField(components, f, f.getGenericType()));
                    }
                });
            Stream.of(current.getDeclaredMethods())
                .filter(it -> isVisible(it, it.getModifiers()))
                .filter(it -> (it.getName().startsWith("get") || it.getName().startsWith("is")) && it.getName().length() > 2)
                .peek(m -> handleRequired(schema, m, () -> findMethodName(m)))
                .forEach(m -> {
                    final String key = findMethodName(m);
                    if (!ignored.test(key) && !schema.getProperties().containsKey(key)) {
                        schema.getProperties().put(key, mapField(components, m, m.getGenericReturnType()));
                    }
                });
            current = current.getSuperclass();
        }
        return schema;
    }

    private Predicate<String> createIgnorePredicate(final Class from) {
        return persistenceCapable != null && persistenceCapable.isAssignableFrom(from) ?
                v -> v.startsWith("pc") : v -> false;
    }

    private boolean isVisible(final AnnotatedElement elt, final int modifiers) {
        final boolean explicit = elt.isAnnotationPresent(Schema.class);
        if (!explicit || !elt.getAnnotation(Schema.class).hidden()) {
            return (!Modifier.isPrivate(modifiers) || elt.isAnnotationPresent(Schema.class)) && !Modifier.isStatic(modifiers);
        }
        return false;
    }

    private Type unwrapType(final Type rawModel) {
        if (ParameterizedType.class.isInstance(rawModel) &&
                Stream.of(ParameterizedType.class.cast(rawModel).getActualTypeArguments()).allMatch(WildcardType.class::isInstance)) {
            return ParameterizedType.class.cast(rawModel).getRawType();
        }
        return rawModel;
    }

    private boolean isStringable(final Type model) {
        return Date.class == model || model.getTypeName().startsWith("java.time.") || Class.class == model || Type.class == model;
    }

    private void handleRequired(final org.eclipse.microprofile.openapi.models.media.Schema schema,
                                final AnnotatedElement element, final Supplier<String> nameSupplier) {
        if (!element.isAnnotationPresent(Schema.class) || !element.getAnnotation(Schema.class).required()) {
            return;
        }
        if (schema.getRequired() == null) {
            schema.required(new ArrayList<>());
        }
        final String name = nameSupplier.get();
        if (!schema.getRequired().contains(name)) {
            schema.getRequired().add(name);
        }
    }

    private org.eclipse.microprofile.openapi.models.media.Schema mapField(final Supplier<Components> components,
                                                                          final AnnotatedElement element,
                                                                          final Type type) {
        final Schema annotation = element.getAnnotation(Schema.class);
        return ofNullable(annotation).map(s -> mapSchema(components, s, null)).orElseGet(() -> {
            final org.eclipse.microprofile.openapi.models.media.Schema schemaFromClass = mapSchemaFromClass(
                    components, type);
            if (annotation != null) {
                mergeSchema(components, schemaFromClass, annotation, type);
            }
            return schemaFromClass;
        });
    }

    private String findFieldName(final Field f) {
        return findSchemaName(f)
                .orElseGet(() -> {
                    if (f.isAnnotationPresent(JsonbProperty.class)) {
                        return f.getAnnotation(JsonbProperty.class).value();
                    }
                    // getter
                    final String fName = f.getName();
                    final String subName = Character.toUpperCase(fName.charAt(0))
                            + (fName.length() > 1 ? fName.substring(1) : "");
                    try {
                        final Method getter = f.getDeclaringClass().getMethod("get" + subName);
                        if (getter.isAnnotationPresent(JsonbProperty.class)) {
                            return getter.getAnnotation(JsonbProperty.class).value();
                        }
                    } catch (final NoSuchMethodException e) {
                        if (boolean.class == f.getType()) {
                            try {
                                final Method isser = f.getDeclaringClass().getMethod("is" + subName);
                                if (isser.isAnnotationPresent(JsonbProperty.class)) {
                                    return isser.getAnnotation(JsonbProperty.class).value();
                                }
                            } catch (final NoSuchMethodException e2) {
                                // no-op
                            }
                        }
                    }
                    return fName;
                });
    }

    private String findMethodName(final Method m) {
        return findSchemaName(m)
                .orElseGet(() -> {
                    if (m.isAnnotationPresent(JsonbProperty.class)) {
                        return m.getAnnotation(JsonbProperty.class).value();
                    }
                    final String name = m.getName();
                    if (name.startsWith("get")) {
                        return decapitalize(name.substring("get".length()));
                    }
                    if (name.startsWith("is")) {
                        return decapitalize(name.substring("is".length()));
                    }
                    return decapitalize(name);
                });
    }

    private Optional<String> findSchemaName(final AnnotatedElement m) {
        return ofNullable(m.getAnnotation(Schema.class))
                .map(Schema::name)
                .filter(it -> !it.isEmpty());
    }

    private void mergeSchema(final Supplier<Components> components,
                             final org.eclipse.microprofile.openapi.models.media.Schema impl,
                             final Schema schema, final Type type) {
        if (schema.deprecated()) {
            impl.deprecated(schema.deprecated());
        }
        if (schema.type() != SchemaType.DEFAULT) {
            impl.type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.valueOf(schema.type().name()));
        }
        if (!schema.title().isEmpty()) {
            impl.title(schema.title());
        }
        if (!schema.description().isEmpty()) {
            impl.description(schema.description());
        }
        if (!schema.format().isEmpty()) {
            impl.format(schema.format());
        }
        if (!schema.ref().isEmpty()) {
            impl.ref(schema.ref());
        }
        final String example = schema.example();
        if (!example.isEmpty()) {
            if (type != null) {
                if (type == double.class || type == Double.class ||
                        type == float.class || type == Float.class) {
                    impl.example(Double.parseDouble(example));
                } else if (type == long.class || type == Long.class ||
                        type == int.class || type == Integer.class ||
                        type == short.class || type == Short.class ||
                        type == byte.class || type == Byte.class) {
                    impl.example(Integer.parseInt(example));
                } else if (type == boolean.class || type == Boolean.class) {
                    impl.example(Boolean.parseBoolean(example));
                } else if (type == String.class) {
                    impl.example(example);
                } else if ((example.startsWith("{") && example.endsWith("}")) ||
                        (example.startsWith("[") && example.endsWith("}"))) {
                    try (final JsonReader reader = jsonReaderFactory.createReader(new StringReader(example))) {
                        impl.example(reader.readValue());
                    } catch (final Exception e) {
                        impl.example(example);
                    }
                } else {
                    impl.example(example);
                }
            } else {
                impl.example(example);
            }
        }
        of(schema.not()).filter(it -> it != Void.class).ifPresent(t -> impl.not(mapSchemaFromClass(components, t)));
        final List<org.eclipse.microprofile.openapi.models.media.Schema> oneOf = Stream.of(schema.oneOf())
                .map(it -> mapSchemaFromClass(components, it)).collect(toList());
        if (!oneOf.isEmpty()) {
            impl.oneOf(oneOf);
        }
        final List<org.eclipse.microprofile.openapi.models.media.Schema> anyOf = Stream.of(schema.anyOf())
                .map(it -> mapSchemaFromClass(components, it)).collect(toList());
        if (!anyOf.isEmpty()) {
            impl.anyOf(anyOf);
        }
        final List<org.eclipse.microprofile.openapi.models.media.Schema> allOf = Stream.of(schema.allOf())
                .map(it -> mapSchemaFromClass(components, it)).collect(toList());
        if (!allOf.isEmpty()) {
            impl.allOf(allOf);
        }
        if (schema.multipleOf() != 0) {
            impl.multipleOf(BigDecimal.valueOf(schema.multipleOf()));
        }
        impl.minimum(toBigDecimal(schema.minimum()));
        impl.maximum(toBigDecimal(schema.maximum()));
        if (schema.exclusiveMinimum()) {
            impl.exclusiveMinimum(schema.exclusiveMinimum());
        }
        if (schema.exclusiveMaximum()) {
            impl.exclusiveMaximum(schema.exclusiveMaximum());
        }
        if (schema.minLength() >= 0 && schema.minLength() != 0) {
            impl.minLength(schema.minLength());
        }
        if (schema.maxLength() >= 0 && schema.maxLength() != Integer.MAX_VALUE) {
            impl.maxLength(schema.maxLength());
        }
        if (!schema.pattern().isEmpty()) {
            impl.pattern(schema.pattern());
        }
        if (schema.nullable()) {
            impl.nullable(schema.nullable());
        }
        if (schema.minProperties() > 0) {
            impl.minProperties(schema.minProperties());
        }
        if (schema.minProperties() > 0) {
            impl.maxProperties(schema.maxProperties());
        }
        if (schema.minItems() < Integer.MAX_VALUE) {
            impl.minItems(schema.minItems());
        }
        if (schema.maxItems() > Integer.MIN_VALUE) {
            impl.maxItems(schema.maxItems());
        }
        if (schema.uniqueItems()) {
            impl.uniqueItems(schema.uniqueItems());
        }
        if (schema.readOnly()) {
            impl.readOnly(schema.readOnly());
        }
        if (schema.writeOnly()) {
            impl.writeOnly(schema.writeOnly());
        }
        impl.defaultValue(toType(schema.defaultValue(), impl.getType()));
        final List<String> required = Stream.of(schema.requiredProperties()).collect(toList());
        if (!required.isEmpty()) {
            impl.required(required);
        }
        if (schema.discriminatorMapping().length > 0) {
            impl.discriminator(new DiscriminatorImpl().mapping(Stream.of(schema.discriminatorMapping())
                    .collect(toMap(DiscriminatorMapping::value, it -> it.schema().getName()))));
        }
        final List<Object> enums = Stream.of(schema.enumeration()).collect(toList());
        if (!enums.isEmpty()) {
            impl.setEnumeration(enums);
        }
    }

    public org.eclipse.microprofile.openapi.models.media.Schema mapSchema(
            final Supplier<org.eclipse.microprofile.openapi.models.Components>components, final Schema schema,
            final String providedRefMapping) {
        if (schema.hidden() || (schema.implementation() == Void.class && schema.name().isEmpty() && schema.ref().isEmpty())) {
            if (schema.type() != SchemaType.DEFAULT) {
                return new SchemaImpl()
                        .type(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType.valueOf(schema.type().name()));
            }
            return null;
        }

        final SchemaImpl impl = new SchemaImpl();
        sets(components, schema, impl, providedRefMapping);
        return impl;
    }

    private void sets(final Supplier<Components> components, final Schema schema,
            final org.eclipse.microprofile.openapi.models.media.Schema impl,
            final String providedRef) {
        if (!schema.ref().isEmpty()) {
            impl.ref(resolveSchemaRef(schema.ref()));
        } else {
            if (schema.implementation() != Void.class) {
                final boolean array = schema.type() == SchemaType.ARRAY;
                if (array) {
                    final SchemaImpl itemSchema = new SchemaImpl();
                    fillSchema(components, schema.implementation(), itemSchema, providedRef);
                    impl.items(itemSchema);
                } else {
                    fillSchema(components, schema.implementation(), impl, providedRef);
                }
            }
            mergeSchema(components, impl, schema, null);
        }
    }

    private String resolveSchemaRef(final String ref) {
        if (ref.startsWith("#")) {
            return ref;
        }
        return "#/components/schemas/" + ref;
    }

    private BigDecimal toBigDecimal(final String minimum) {
        return minimum.isEmpty() ? null : new BigDecimal(minimum);
    }

    private Object toType(final String s, final org.eclipse.microprofile.openapi.models.media.Schema.SchemaType type) {
        if (type == null || s.isEmpty()) {
            return null;
        }
        switch (type) {
        case STRING:
            return s;
        case INTEGER:
            return Integer.valueOf(s);
        case NUMBER:
            return Double.valueOf(s);
        case BOOLEAN:
            return Boolean.parseBoolean(s);
        case OBJECT:
        case ARRAY:
            // todo using jsonb
        default:
            return null;
        }
    }
}
