/*
 * 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.johnzon.jsonschema.generator;

import javax.json.JsonObject;
import javax.json.JsonString;
import javax.json.JsonValue;
import javax.json.bind.annotation.JsonbProperty;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static java.util.Collections.singletonMap;
import static java.util.Comparator.comparing;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;

// todo: support ref resolution for schema and avoid to generate as much classes as attributes
public class PojoGenerator {
    private final PojoConfiguration configuration;

    protected final Set<String> imports = new TreeSet<>(String::compareTo);
    protected final List<Attribute> attributes = new ArrayList<>();
    protected final Map<String, String> nested = new TreeMap<>(String::compareTo);

    public PojoGenerator(final PojoConfiguration configuration) {
        this.configuration = configuration;
    }

    public PojoGenerator setNested(final Map<String, String> nested) {
        this.nested.putAll(nested);
        return this;
    }

    public Map<String, String> generate() {
        final String name = configuration.getPackageName() + '.' + configuration.getClassName();
        final String path = name.replace('.', '/') + ".java";
        attributes.sort(comparing(a -> a.javaName));
        if (!attributes.isEmpty()) {
            imports.add(Objects.class.getName());
        }
        final String content = "" +
                "package " + configuration.getPackageName() + ";\n" +
                "\n" +
                (imports.isEmpty() ? "" : imports.stream()
                        .sorted()
                        .map(it -> "import " + it + ";")
                        .collect(joining("\n", "", "\n\n"))) +
                "public class " + configuration.getClassName() + afterClassName() + " {\n" +
                (attributes.isEmpty() ?
                        ("" +
                                "    @Override\n" +
                                "    public int hashCode() {\n" +
                                "        return 0;\n" +
                                "    }\n" +
                                "\n" +
                                "    @Override\n" +
                                "    public boolean equals(final Object other) {\n" +
                                "        return other instanceof " + configuration.getClassName() + ";\n" +
                                "    }\n" +
                                "}\n") :
                        (attributes.stream()
                                .map(a -> "" +
                                        (configuration.isAddJsonbProperty() && !Objects.equals(a.javaName, a.jsonName) ?
                                                "    @JsonbProperty(\"" + a.jsonName.replace("\"", "\\\"") + "\")\n" :
                                                "") +
                                        "    private " + a.type + " " + a.javaName + ";")
                                .collect(joining("\n", "", "\n\n")) +
                                (configuration.isAddAllArgsConstructor() ?
                                        "    public " + configuration.getClassName() + "() {\n" +
                                                "        // no-op\n" +
                                                "    }\n" +
                                                "\n" +
                                                "    public " + configuration.getClassName() + "(" +
                                                attributes.stream()
                                                        .map(a -> "final " + a.type + " " + a.javaName)
                                                        .collect(joining(
                                                                ",\n" + IntStream.range(
                                                                                0,
                                                                                "    public (".length() +
                                                                                        configuration.getClassName().length())
                                                                        .mapToObj(i -> " ")
                                                                        .collect(joining()),
                                                                "",
                                                                ") {\n" +
                                                                        "        // no-op\n" +
                                                                        "    }\n\n")) :
                                        "") +
                                attributes.stream()
                                        .map(a -> {
                                            final String marker = Character.toUpperCase(a.javaName.charAt(0)) + a.javaName.substring(1);
                                            return "" +
                                                    "    public " + a.type + " get" + Character.toUpperCase(a.javaName.charAt(0)) + a.javaName.substring(1) + "() {\n" +
                                                    "        return " + a.javaName + ";\n" +
                                                    "    }\n" +
                                                    "\n" +
                                                    "    public " +
                                                    (configuration.isFluentSetters() ? a.type : "void") +
                                                    " set" + marker + "(final " + a.type + " " + a.javaName + ") {\n" +
                                                    "        this." + a.javaName + " = " + a.javaName + ";\n" +
                                                    (configuration.isFluentSetters() ? "    return this;\n" : "") +
                                                    "    }\n" +
                                                    "";
                                        })
                                        .collect(joining("\n", "", "\n")) +
                                "    @Override\n" +
                                "    public int hashCode() {\n" +
                                "        return Objects.hash(\n" +
                                attributes.stream()
                                        .map(a -> a.javaName)
                                        .collect(joining(",\n                ", "                ", ");\n")) +
                                "    }\n" +
                                "\n" +
                                "    @Override\n" +
                                "    public boolean equals(final Object __other) {\n" +
                                "        if (!(__other instanceof " + configuration.getClassName() + ")) {\n" +
                                "            return false;\n" +
                                "        }\n" +
                                "        final " + configuration.getClassName() + " __otherCasted = (" + configuration.getClassName() + ") __other;\n" +
                                "        return " + attributes.stream()
                                .map(a -> a.javaName)
                                .map(it -> "Objects.equals(" + it + ", __otherCasted." + it + ")")
                                .collect(joining(" &&\n            ")) + ";\n" +
                                "    }\n"
                        )) +
                beforeClassEnd() +
                "}\n";
        if (nested.isEmpty()) {
            return singletonMap(path, content);
        }
        return Stream.concat(
                        nested.entrySet().stream(),
                        Stream.of(new AbstractMap.SimpleImmutableEntry<>(path, content)))
                .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, () -> new TreeMap<>(String::compareTo)));
    }

    public PojoGenerator visitSchema(final JsonObject schema) {
        if (!schema.containsKey("properties")) {
            throw new IllegalArgumentException("Unsupported schema since it does not contain any properties: " + schema);
        }

        final JsonObject properties = getValueAs(schema, "properties", JsonObject.class);
        final JsonValue required = schema.get("required");
        final List<String> requiredAttrs = required != null && required.getValueType() == JsonValue.ValueType.ARRAY ?
                required.asJsonArray().stream().map(JsonString.class::cast).map(JsonString::getString).collect(toList()) :
                null;
        attributes.addAll(properties.entrySet().stream()
                .map(e -> {
                    final String javaName = toJavaName(e.getKey());
                    return new Attribute(
                            javaName, e.getKey(),
                            asType(javaName, e.getValue().asJsonObject(), requiredAttrs != null && requiredAttrs.contains(e.getKey())));
                })
                .collect(toList()));

        return this;
    }

    /**
     * @param ref the reference to resolve.
     * @return the reference class name if resolved else null.
     */
    protected String onRef(final Ref ref) {
        if (configuration.getOnRef() != null) {
            return configuration.getOnRef().apply(ref);
        }
        return null; // todo: check if already in nested for ex
    }

    protected String beforeClassEnd() {
        return "";
    }

    protected String afterClassName() {
        return "";
    }

    protected String asType(final String javaName, final JsonObject schema, final boolean required) {
        final JsonValue ref = schema.get("$ref");
        if (ref != null && ref.getValueType() == JsonValue.ValueType.STRING) {
            final String name = onRef(new Ref(
                    JsonString.class.cast(ref).getString(), configuration.getClassName(), imports, attributes, nested));
            if (name != null) {
                return name;
            }
        }

        final JsonValue value = schema.get("type");
        String type;
        if (value == null) {
            if (schema.containsKey("properties") || schema.containsKey("additionalProperties")) {
                type = "object";
            } else if (schema.containsKey("items")) {
                type = "array";
            } else { // unknown, don't fail for wrongly written schema
                imports.add(JsonValue.class.getName());
                return JsonValue.class.getSimpleName();
            }
        } else {
            type = JsonString.class.cast(value).getString();
        }
        final JsonValue formatValue = schema.get("date-time");
        if (formatValue != null && formatValue.getValueType() == JsonValue.ValueType.STRING) {
            type = JsonString.class.cast(formatValue).getString();
        }

        switch (type) {
            case "array":
                final JsonObject items = getValueAs(schema, "items", JsonObject.class);
                final String itemType = onItemSchema(javaName, items);
                imports.add(List.class.getName());
                return List.class.getSimpleName() + "<" + itemType + ">";
            case "object":
                return onObjectAttribute(javaName, schema);
            case "null":
                imports.add(JsonValue.class.getName());
                return JsonValue.class.getSimpleName();
            case "boolean":
                return required ? "boolean" : "Boolean";
            case "string":
                final JsonValue enumList = schema.get("enum");
                if (enumList != null && enumList.getValueType() == JsonValue.ValueType.ARRAY) {
                    return onEnum(javaName, enumList);
                }
                return "String";
            case "number":
            case "double": // openapi
                return required ? "double" : "Double";
            // openapi types
            case "int":
            case "int32":
            case "integer":
                return required ? "int" : "Integer";
            case "int64":
            case "long":
                return required ? "long" : "Long";
            case "float":
                return required ? "float" : "Float";
            case "date":
                imports.add(LocalDate.class.getName());
                return LocalDate.class.getSimpleName();
            case "duration":
                imports.add(Duration.class.getName());
                return Duration.class.getSimpleName();
            case "date-time":
            case "dateTime":
                imports.add(OffsetDateTime.class.getName());
                return OffsetDateTime.class.getSimpleName();
            case "time":
                imports.add(LocalTime.class.getName());
                return LocalTime.class.getSimpleName();
            case "byte":
                return "byte[]";
            case "uuid":
            case "hostname":
            case "idn-hostname":
            case "email":
            case "idn-email":
            case "ipv4":
            case "ipv6":
            case "uri":
            case "uri-reference":
            case "iri":
            case "iri-reference":
            case "uri-template":
            case "json-pointer":
            case "relative-json-pointer":
            case "regex":
            case "binary": // base64
            case "password":
                return "String";
            default:
                throw new IllegalArgumentException("Unsupported type: " + type);
        }
    }

    protected String onEnum(final String javaName, final JsonValue enumList) {
        final String className = configuration.getClassName() + Character.toUpperCase(javaName.charAt(0)) + javaName.substring(1);
        final Map<String, String> values = enumList.asJsonArray().stream()
                .map(JsonString.class::cast)
                .map(JsonString::getString)
                .collect(toMap(identity(), this::toJavaName));
        final boolean injectValues = !values.keySet().equals(new HashSet<>(values.values())); // java != json
        nested.put(
                configuration.getPackageName().replace('.', '/') + '/' + className + ".java", "" +
                        "package " + configuration.getPackageName() + ";\n" +
                        "\n" +
                        "public enum " + className + " {\n" +
                        values.entrySet().stream()
                                .map(it -> "" +
                                        (injectValues && configuration.isAddJsonbProperty() ?
                                                "    @JsonbProperty(\"" + it.getKey().replace("\"", "\\\"") + "\")\n" :
                                                "") +
                                        "    " + it.getValue() +
                                        (injectValues ? "(\"" + it.getKey().replace("\"", "\\\"") + "\")" : ""))
                                .collect(joining(",\n", "", injectValues ? ";\n\n" : "\n")) +
                        (injectValues ?
                                "" +
                                        "    private String value;\n" +
                                        "\n" +
                                        "    " + className + "(final String value) {\n" +
                                        "        this.value = value;\n" +
                                        "    }\n" +
                                        "\n" +
                                        "    public String toString() {\n" +
                                        "        return value;\n" +
                                        "    }\n" +
                                        "" :
                                "") +
                        "}\n");
        return className;
    }

    protected String onObjectAttribute(final String javaName, final JsonObject schema) {
        final JsonValue additionalProperties = schema.get("additionalProperties");
        final JsonValue properties = schema.get("properties");
        final boolean hasProperties = properties != null && properties.getValueType() == JsonValue.ValueType.OBJECT;
        if (!hasProperties &&
                additionalProperties != null &&
                additionalProperties.getValueType() == JsonValue.ValueType.OBJECT) {
            final JsonObject propSchema = additionalProperties.asJsonObject();
            final JsonValue propTypeValue = propSchema.get("type");
            if (propTypeValue != null && propTypeValue.getValueType() == JsonValue.ValueType.STRING) {
                String propType = JsonString.class.cast(propTypeValue).getString();
                final JsonValue formatValue = schema.get("date-time");
                if (formatValue != null && formatValue.getValueType() == JsonValue.ValueType.STRING) {
                    propType = JsonString.class.cast(formatValue).getString();
                }
                switch (propType) {
                    case "uuid":
                    case "hostname":
                    case "idn-hostname":
                    case "email":
                    case "idn-email":
                    case "ipv4":
                    case "ipv6":
                    case "uri":
                    case "uri-reference":
                    case "iri":
                    case "iri-reference":
                    case "uri-template":
                    case "json-pointer":
                    case "relative-json-pointer":
                    case "regex":
                    case "string":
                    case "binary":
                    case "password":
                        imports.add(Map.class.getName());
                        return "Map<String, String>";
                    case "boolean":
                        imports.add(Map.class.getName());
                        return "Map<String, Boolean>";
                    case "number":
                    case "double":
                        imports.add(Map.class.getName());
                        return "Map<String, Double>";
                    case "int":
                    case "int32":
                    case "integer":
                        imports.add(Map.class.getName());
                        return "Map<String, Integer>";
                    case "int64":
                    case "long":
                        imports.add(Map.class.getName());
                        return "Map<String, Long>";
                    case "float":
                        imports.add(Map.class.getName());
                        return "Map<String, Float>";
                    case "date":
                        imports.add(Map.class.getName());
                        imports.add(LocalDate.class.getName());
                        return "Map<String, LocalDate>";
                    case "dateTime":
                    case "date-time":
                        imports.add(Map.class.getName());
                        imports.add(OffsetDateTime.class.getName());
                        return "Map<String, OffsetDateTime>";
                    case "duration":
                        imports.add(Map.class.getName());
                        imports.add(Duration.class.getName());
                        return "Map<String, Duration>";
                    case "time":
                        imports.add(Map.class.getName());
                        imports.add(LocalTime.class.getName());
                        return "Map<String, LocalTime>";
                    default:
                        // todo: case array, object
                }
            }
        } else if (hasProperties) {
            final String className = configuration.getClassName() + Character.toUpperCase(javaName.charAt(0)) + javaName.substring(1);
            nested.putAll(newSubPojoGenerator(new PojoConfiguration()
                    .setPackageName(configuration.getPackageName())
                    .setClassName(className)
                    .setAddJsonbProperty(configuration.isAddJsonbProperty())
                    .setAddAllArgsConstructor(configuration.isAddAllArgsConstructor())
                    .setOnRef(configuration.getOnRef()))
                    .visitSchema(schema)
                    .generate());
            return className;
        }

        imports.add(JsonObject.class.getName());
        return JsonObject.class.getSimpleName();
    }

    protected PojoGenerator newSubPojoGenerator(final PojoConfiguration pojoConfiguration) {
        return new PojoGenerator(pojoConfiguration);
    }

    protected String onItemSchema(final String javaName, final JsonObject schema) {
        final JsonValue ref = schema.get("$ref");
        if (ref != null && ref.getValueType() == JsonValue.ValueType.STRING) {
            final String name = onRef(new Ref(
                    JsonString.class.cast(ref).getString(), configuration.getClassName(),
                    imports, attributes, nested));
            if (name != null) {
                return name;
            }
        }

        final JsonValue propTypeValue = schema.get("type");
        if (propTypeValue != null && propTypeValue.getValueType() == JsonValue.ValueType.STRING) {
            String type = JsonString.class.cast(propTypeValue).getString();
            final JsonValue formatValue = schema.get("date-time");
            if (formatValue != null && formatValue.getValueType() == JsonValue.ValueType.STRING) {
                type = JsonString.class.cast(formatValue).getString();
            }
            switch (type) {
                case "array":
                    throw new IllegalStateException("Array of array unsupported");
                case "object":
                    final String className = configuration.getClassName() + Character.toUpperCase(javaName.charAt(0)) + javaName.substring(1);
                    nested.putAll(newSubPojoGenerator(new PojoConfiguration()
                            .setPackageName(configuration.getPackageName())
                            .setClassName(className)
                            .setAddJsonbProperty(configuration.isAddJsonbProperty())
                            .setAddAllArgsConstructor(configuration.isAddAllArgsConstructor())
                            .setOnRef(configuration.getOnRef()))
                            .visitSchema(schema)
                            .generate());
                    return className;
                case "null":
                    imports.add(JsonValue.class.getName());
                    return JsonValue.class.getSimpleName();
                case "boolean":
                    return "Boolean";
                case "uuid":
                case "hostname":
                case "idn-hostname":
                case "email":
                case "idn-email":
                case "ipv4":
                case "ipv6":
                case "uri":
                case "uri-reference":
                case "iri":
                case "iri-reference":
                case "uri-template":
                case "json-pointer":
                case "relative-json-pointer":
                case "regex":
                case "string":
                case "binary":
                case "password":
                    return "String";
                case "number":
                case "double":
                    return "Double";
                case "int":
                case "int32":
                case "integer":
                    return "Integer";
                case "int64":
                case "long":
                    return "Long";
                case "float":
                    return "Float";
                case "date":
                    imports.add(LocalDate.class.getName());
                    return LocalDate.class.getSimpleName();
                case "dateTime":
                    imports.add(OffsetDateTime.class.getName());
                    return OffsetDateTime.class.getSimpleName();
                case "duration":
                    imports.add(Duration.class.getName());
                    return Duration.class.getSimpleName();
                case "time":
                    imports.add(LocalTime.class.getName());
                    return LocalTime.class.getSimpleName();
                case "byte":
                    return "byte[]";
                default:
                    throw new IllegalArgumentException("Unsupported type: " + type);
            }
        }

        imports.add(JsonValue.class.getName());
        return JsonValue.class.getSimpleName();
    }

    private String toJavaName(final String key) {
        String name = key.chars()
                .mapToObj(i -> Character.toString(!Character.isJavaIdentifierPart(i) ? '_' : (char) i))
                .collect(joining());
        if (Character.isDigit(name.charAt(0))) {
            name = "a" + name;
        }
        while (!name.isEmpty() && (!Character.isJavaIdentifierStart(name.charAt(0)) || name.charAt(0) == '_' || name.charAt(0) == '$')) {
            name = name.substring(1);
        }
        if (name.isEmpty()) {
            throw new IllegalArgumentException("Can't find a name for '" + key + "'");
        }

        if (isReserved(name)) {
            name += "Value";
        }

        if (name.contains("_")) {
            name = toCamelCase(name);
        }

        if (!Objects.equals(key, name) && configuration.isAddJsonbProperty()) {
            imports.add(JsonbProperty.class.getName());
        }
        return name;
    }

    protected String toCamelCase(final String name) {
        final StringBuilder out = new StringBuilder(name.length());
        boolean up = false;
        for (final char c : name.toCharArray()) {
            if (up) {
                out.append(Character.toUpperCase(c));
                up = false;
            } else if (c == '_') {
                up = true;
            } else {
                out.append(c);
            }
        }
        return out.toString();
    }

    protected boolean isReserved(final String name) {
        return "continue".equals(name) || "break".equals(name) || "default".equals(name) ||
                "do".equals(name) || "while".equals(name) ||
                "for".equals(name) ||
                "if".equals(name) || "else".equals(name) ||
                "enum".equals(name) ||
                "int".equals(name) ||
                "long".equals(name) ||
                "float".equals(name) ||
                "double".equals(name) ||
                "boolean".equals(name) ||
                "byte".equals(name) ||
                "char".equals(name) ||
                "short".equals(name) ||
                "String".equals(name);
    }

    private static <T> T getValueAs(final JsonObject schema, final String attribute, final Class<T> type) {
        final JsonValue value = schema.get(attribute);
        if (value == null) {
            throw new IllegalArgumentException("No \"" + attribute + "\" value in " + schema);
        }
        return valueAs(schema, type, value);
    }

    private static <T> T valueAs(final JsonObject schema, final Class<T> type, final JsonValue value) {
        if (!type.isInstance(value)) {
            throw new IllegalArgumentException("\"items\" not an object: " + schema);
        }
        return type.cast(value);
    }

    public static class PojoConfiguration {
        private String packageName = "org.apache.johnzon.generated.pojo";
        private String className;
        private boolean addJsonbProperty = true;
        private boolean addAllArgsConstructor = true;
        private boolean fluentSetters = false;
        private Function<Ref, String> onRef;

        public Function<Ref, String> getOnRef() {
            return onRef;
        }

        public PojoConfiguration setOnRef(final Function<Ref, String> onRef) {
            this.onRef = onRef;
            return this;
        }

        public boolean isFluentSetters() {
            return fluentSetters;
        }

        public PojoConfiguration setFluentSetters(final boolean fluentSetters) {
            this.fluentSetters = fluentSetters;
            return this;
        }

        public boolean isAddAllArgsConstructor() {
            return addAllArgsConstructor;
        }

        public PojoConfiguration setAddAllArgsConstructor(final boolean addAllArgsConstructor) {
            this.addAllArgsConstructor = addAllArgsConstructor;
            return this;
        }

        public boolean isAddJsonbProperty() {
            return addJsonbProperty;
        }

        public PojoConfiguration setAddJsonbProperty(final boolean addJsonbProperty) {
            this.addJsonbProperty = addJsonbProperty;
            return this;
        }

        public String getClassName() {
            return className;
        }

        public PojoConfiguration setClassName(final String className) {
            this.className = className;
            return this;
        }

        public String getPackageName() {
            return packageName;
        }

        public PojoConfiguration setPackageName(final String packageName) {
            this.packageName = packageName;
            return this;
        }
    }

    protected static class Attribute {
        private final String javaName;
        private final String jsonName;
        private final String type;

        protected Attribute(final String javaName, final String jsonName, final String type) {
            this.javaName = javaName;
            this.jsonName = jsonName;
            this.type = type;
        }
    }

    public static class Ref {
        private final String ref;
        private final String enclosingClass;
        private final Set<String> imports;
        private final List<Attribute> attributes;
        private final Map<String, String> nested;

        private Ref(final String ref, final String enclosingClass, final Set<String> imports,
                    final List<Attribute> attributes, final Map<String, String> nested) {
            this.ref = ref;
            this.enclosingClass = enclosingClass;
            this.imports = imports;
            this.attributes = attributes;
            this.nested = nested;
        }

        public String getEnclosingClass() {
            return enclosingClass;
        }

        public String getRef() {
            return ref;
        }

        public Set<String> getImports() {
            return imports;
        }

        public List<Attribute> getAttributes() {
            return attributes;
        }

        public Map<String, String> getNested() {
            return nested;
        }
    }
}
