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

}
