/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed 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.onosproject.maven;

import com.thoughtworks.qdox.JavaProjectBuilder;
import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * Produces ONOS component configuration catalogue resources.
 */
@Mojo(name = "cfg", defaultPhase = LifecyclePhase.GENERATE_RESOURCES)
@java.lang.SuppressWarnings("squid:S1148")
public class OnosCfgMojo extends AbstractMojo {

    private static final String COMPONENT = "org.apache.felix.scr.annotations.Component";
    private static final String PROPERTY = "org.apache.felix.scr.annotations.Property";
    private static final String SEP = "|";

    /**
     * The directory where the generated catalogue file will be put.
     */
    @Parameter(defaultValue = "${basedir}")
    protected File srcDirectory;

    /**
     * The directory where the generated catalogue file will be put.
     */
    @Parameter(defaultValue = "${project.build.outputDirectory}")
    protected File dstDirectory;

    @Override
    public void execute() throws MojoExecutionException {
        getLog().info("Generating ONOS component configuration catalogues...");
        try {
            JavaProjectBuilder builder = new JavaProjectBuilder();
            builder.addSourceTree(new File(srcDirectory, "src/main/java"));
            builder.getClasses().forEach(this::processClass);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    private void processClass(JavaClass javaClass) {
        boolean isComponent = javaClass.getAnnotations().stream()
                .map(ja -> ja.getType().getName().equals(COMPONENT))
                .findFirst().isPresent();
        if (isComponent) {
            List<String> lines = new ArrayList<>();
            javaClass.getFields().forEach(field -> processField(lines, javaClass, field));
            if (!lines.isEmpty()) {
                writeCatalog(javaClass, lines);
            }
        }
    }

    private void writeCatalog(JavaClass javaClass, List<String> lines) {
        File dir = new File(dstDirectory, javaClass.getPackageName().replace('.', '/'));
        dir.mkdirs();

        File cfgDef = new File(dir, javaClass.getName().replace('.', '/') + ".cfgdef");
        try (FileWriter fw = new FileWriter(cfgDef);
             PrintWriter pw = new PrintWriter(fw)) {
            pw.println("# This file is auto-generated by onos-maven-plugin");
            lines.forEach(pw::println);
        } catch (IOException e) {
            System.err.println("Unable to write catalog for " + javaClass.getName());
            e.printStackTrace();
        }
    }

    private void processField(List<String> lines, JavaClass javaClass, JavaField field) {
        field.getAnnotations().forEach(ja -> {
            if (ja.getType().getName().equals(PROPERTY)) {
                lines.add(expand(javaClass, ja.getNamedParameter("name").toString()) +
                                  SEP + type(field) +
                                  SEP + defaultValue(javaClass, field, ja) +
                                  SEP + description(ja));
            }
        });
    }

    // TODO: Stuff below is very much hack-ish and should be redone; it works for now though.

    private String description(JavaAnnotation annotation) {
        String description = (String) annotation.getNamedParameter("label");
        return description.replaceAll("\" \\+ \"", "")
                .replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", "");
    }

    private String type(JavaField field) {
        String ft = field.getType().getName().toUpperCase();
        return ft.equals("INT") ? "INTEGER" : ft;
    }

    private String defaultValue(JavaClass javaClass, JavaField field,
                                JavaAnnotation annotation) {
        String ft = field.getType().getName().toLowerCase();
        String defValueName = ft.equals("boolean") ? "boolValue" :
                ft.equals("string") ? "value" : ft + "Value";
        Object dv = annotation.getNamedParameter(defValueName);
        return dv == null ? "" : expand(javaClass, dv.toString());
    }

    private String stripQuotes(String string) {
        return string.trim().replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", "");
    }

    private String expand(JavaClass javaClass, String value) {
        JavaField field = javaClass.getFieldByName(value);
        return field == null ? stripQuotes(value) :
                stripQuotes(field.getCodeBlock().replaceFirst(".*=", "").replaceFirst(";$", ""));
    }

}
