/*
 * 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)
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(";$", ""));
    }

}
