/*
 * 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.camel.tools.apt;

import java.io.Writer;
import java.util.Set;

import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;

import org.apache.camel.tools.apt.helper.IOHelper;

import static org.apache.camel.tools.apt.AnnotationProcessorHelper.dumpExceptionToErrorFile;

public final class PropertyPlaceholderGenerator {

    private PropertyPlaceholderGenerator() {
    }

    public static void generatePropertyPlaceholderProviderSource(ProcessingEnvironment processingEnv, TypeElement parent,
                                                                 String def, String fqnDef, String cn, String fqn,
                                                                 Set<CoreEipAnnotationProcessorHelper.EipOption> options) {

        Writer w = null;
        try {
            JavaFileObject src = processingEnv.getFiler().createSourceFile(fqn, parent);
            w = src.openWriter();

            w.write("/* Generated by org.apache.camel:apt */\n");
            w.write("package org.apache.camel.model.placeholder;\n");
            w.write("\n");
            w.write("import java.util.HashMap;\n");
            w.write("import java.util.Map;\n");
            w.write("import java.util.function.Consumer;\n");
            w.write("import java.util.function.Supplier;\n");
            w.write("\n");
            w.write("import org.apache.camel.CamelContext;\n");
            w.write("import " + fqnDef + ";\n");
            w.write("import org.apache.camel.spi.PropertyPlaceholderConfigurer;\n");
            w.write("\n");
            w.write("/**\n");
            w.write(" * Source code generated by org.apache.camel:apt\n");
            w.write(" */\n");
            w.write("public class " + cn + " implements PropertyPlaceholderConfigurer {\n");
            w.write("\n");
            w.write("    private final Map<String, Supplier<String>> readPlaceholders = new HashMap<>();\n");
            w.write("    private final Map<String, Consumer<String>> writePlaceholders = new HashMap<>();\n");
            w.write("\n");

            // add constructor
            w.write("    public " + cn + "(Object obj) {\n");
            w.write("        " + def + " definition = (" + def + ") obj;\n");
            w.write("\n");

            // only include string types as they are the only ones we can use for property placeholders
            boolean found = false;
            for (CoreEipAnnotationProcessorHelper.EipOption option : options) {
                if ("java.lang.String".equals(option.getType())) {
                    found = true;
                    String getOrSet = sanitizePropertyPlaceholderOptionName(def, option);
                    getOrSet = Character.toUpperCase(getOrSet.charAt(0)) + getOrSet.substring(1);
                    w.write("        readPlaceholders.put(\"" + option.getName() + "\", definition::get" + getOrSet + ");\n");
                    w.write("        writePlaceholders.put(\"" + option.getName() + "\", definition::set" + getOrSet + ");\n");
                }
            }
            if (!found) {
                w.write("\n");
            }

            w.write("    }\n");
            w.write("\n");
            w.write("    @Override\n");
            w.write("    public Map<String, Supplier<String>> getReadPropertyPlaceholderOptions(CamelContext camelContext) {\n");
            w.write("        return readPlaceholders;\n");
            w.write("    }\n");
            w.write("\n");
            w.write("    @Override\n");
            w.write("    public Map<String, Consumer<String>> getWritePropertyPlaceholderOptions(CamelContext camelContext) {\n");
            w.write("        return writePlaceholders;\n");
            w.write("    }\n");
            w.write("\n");
            w.write("}\n");
            w.write("\n");
        } catch (Exception e) {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Unable to generate source code file: " + fqn + ": " + e.getMessage());
            dumpExceptionToErrorFile("camel-apt-error.log", "Unable to generate source code file: " + fqn, e);
        } finally {
            IOHelper.close(w);
        }
    }

    public static void generatePropertyPlaceholderDefinitionsHelper(ProcessingEnvironment processingEnv, RoundEnvironment roundEnv,
                                                                    Set<String> propertyPlaceholderDefinitions) {

        String fqn = "org.apache.camel.model.placeholder.DefinitionPropertiesPlaceholderProviderHelper";

        Writer w = null;
        try {
            JavaFileObject src = processingEnv.getFiler().createSourceFile(fqn);
            w = src.openWriter();

            w.write("/* Generated by camel-apt */\n");
            w.write("package org.apache.camel.model.placeholder;\n");
            w.write("\n");
            w.write("import java.util.HashMap;\n");
            w.write("import java.util.Map;\n");
            w.write("import java.util.Optional;\n");
            w.write("import java.util.function.Function;\n");
            w.write("import java.util.function.Supplier;\n");
            w.write("\n");
            w.write("import org.apache.camel.spi.PropertyPlaceholderConfigurer;\n");
            for (String def : propertyPlaceholderDefinitions) {
                w.write("import " + def + ";\n");
            }
            w.write("\n");
            w.write("/**\n");
            w.write(" * Source code generated by org.apache.camel:apt\n");
            w.write(" */\n");
            w.write("public class DefinitionPropertiesPlaceholderProviderHelper {\n");
            w.write("\n");
            w.write("    private static final Map<Class, Function<Object, PropertyPlaceholderConfigurer>> MAP;\n");
            w.write("    static {\n");
            w.write("        Map<Class, Function<Object, PropertyPlaceholderConfigurer>> map = new HashMap<>(" + propertyPlaceholderDefinitions.size() + ");\n");
            for (String def : propertyPlaceholderDefinitions) {
                String cn = def.substring(def.lastIndexOf('.') + 1);
                w.write("        map.put(" + cn + ".class, " + cn + "PropertyPlaceholderProvider::new);\n");
            }
            w.write("        MAP = map;\n");
            w.write("    }\n");
            w.write("\n");
            w.write("    public static Optional<PropertyPlaceholderConfigurer> provider(Object definition) {\n");
            w.write("        Function<Object, PropertyPlaceholderConfigurer> func = MAP.get(definition.getClass());\n");
            w.write("        if (func != null) {\n");
            w.write("            return Optional.of(func.apply(definition));\n");
            w.write("        }\n");
            w.write("        return Optional.empty();\n");
            w.write("    }\n");
            w.write("\n");
            w.write("}\n");
            w.write("\n");
        } catch (Exception e) {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Unable to generate source code file: " + fqn + ": " + e.getMessage());
            dumpExceptionToErrorFile("camel-apt-error.log", "Unable to generate source code file: " + fqn, e);
        } finally {
            IOHelper.close(w);
        }
    }

    /**
     * Some models have different setter/getter names vs the xml name (eg as defined in @XmlAttribute).
     * So we need to correct this using this method.
     */
    private static String sanitizePropertyPlaceholderOptionName(String def, CoreEipAnnotationProcessorHelper.EipOption option) {
        if ("SimpleExpression".equals(def) || "JsonPathExpression".equals(def)) {
            if ("resultType".equals(option.getName())) {
                return "resultTypeName";
            }
        } else if ("EnrichDefinition".equals(def) || "PollEnrichDefinition".equals(def) || "ClaimCheckDefinition".equals(def)) {
            if ("strategyRef".equals(option.getName())) {
                return "aggregationStrategyRef";
            } else if ("strategyMethodName".equals(option.getName())) {
                return "aggregationStrategyMethodName";
            } else if ("strategyMethodAllowNull".equals(option.getName())) {
                return "aggregationStrategyMethodAllowNull";
            }
        } else if ("MethodCallExpression".equals(def)) {
            if ("beanType".equals(option.getName())) {
                return "beanTypeName";
            }
        } else if ("XPathExpression".equals(def)) {
            if ("documentType".equals(option.getName())) {
                return "documentTypeName";
            } else if ("resultType".equals(option.getName())) {
                return "resultTypeName";
            }
        } else if ("WireTapDefinition".equals(def)) {
            if ("processorRef".equals(option.getName())) {
                return "newExchangeProcessorRef";
            }
        } else if ("TidyMarkupDataFormat".equals(def)) {
            if ("dataObjectType".equals(option.getName())) {
                return "dataObjectTypeName";
            }
        } else if ("BindyDataFormat".equals(def)) {
            if ("classType".equals(option.getName())) {
                return "classTypeAsString";
            }
        }

        return option.getName();
    }

}
