package org.onlab.jdvue;


import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.google.common.base.Objects.toStringHelper;

/**
 * Produces a package &amp; source catalogue.
 *
 * @author Thomas Vachuska
 */
public class Catalog {

    private static final String PACKAGE = "package";
    private static final String IMPORT = "import";
    private static final String STATIC = "static";
    private static final String SRC_ROOT = "src/main/java/";
    private static final String WILDCARD = "\\.*$";

    private final Map<String, JavaSource> sources = new HashMap<>();
    private final Map<String, JavaPackage> packages = new HashMap<>();
    private final Set<DependencyCycle> cycles = new HashSet<>();
    private final Set<Dependency> cycleSegments = new HashSet<>();
    private final Map<JavaPackage, Set<DependencyCycle>> packageCycles = new HashMap<>();
    private final Map<JavaPackage, Set<Dependency>> packageCycleSegments = new HashMap<>();

    /**
     * Loads the catalog from the specified catalog file.
     *
     * @param catalogPath catalog file path
     * @throws IOException if unable to read the catalog file
     */
    public void load(String catalogPath) throws IOException {
        InputStream is = new FileInputStream(catalogPath);
        BufferedReader br = new BufferedReader(new InputStreamReader(is));

        String line;
        while ((line = br.readLine()) != null) {
            // Split the line into the two fields: path and pragmas
            String fields[] = line.trim().split(":");
            if (fields.length <= 1) {
                continue;
            }
            String path = fields[0];

            // Now split the pragmas on whitespace and trim punctuation
            String pragma[] = fields[1].trim().replaceAll("[;\n\r]", "").split("[\t ]");

            // Locate (or create) Java source entity based on the path
            JavaSource source = getOrCreateSource(path);

            // Now process the package or import statements
            if (pragma[0].equals(PACKAGE)) {
                processPackageDeclaration(source, pragma[1]);

            } else if (pragma[0].equals(IMPORT)) {
                if (pragma[1].equals(STATIC)) {
                    processImportStatement(source, pragma[2]);
                } else {
                    processImportStatement(source, pragma[1]);
                }
            }
        }
    }

    /**
     * Analyzes the catalog by resolving imports and identifying circular
     * package dependencies.
     */
    public void analyze() {
        resolveImports();
        findCircularDependencies();
    }

    /**
     * Identifies circular package dependencies through what amounts to be a
     * depth-first search rooted with each package.
     */
    private void findCircularDependencies() {
        cycles.clear();
        for (JavaPackage javaPackage : getPackages()) {
            findCircularDependencies(javaPackage);
        }

        cycleSegments.clear();
        packageCycles.clear();
        packageCycleSegments.clear();

        for (DependencyCycle cycle : getCycles()) {
            recordCycleForPackages(cycle);
            cycleSegments.addAll(cycle.getCycleSegments());
        }
    }

    /**
     * Records the specified cycle into a set for each involved package.
     *
     * @param cycle cycle to record for involved packages
     */
    private void recordCycleForPackages(DependencyCycle cycle) {
        for (JavaPackage javaPackage : cycle.getCycle()) {
            Set<DependencyCycle> cset = packageCycles.get(javaPackage);
            if (cset == null) {
                cset = new HashSet<>();
                packageCycles.put(javaPackage, cset);
            }
            cset.add(cycle);

            Set<Dependency> sset = packageCycleSegments.get(javaPackage);
            if (sset == null) {
                sset = new HashSet<>();
                packageCycleSegments.put(javaPackage, sset);
            }
            sset.addAll(cycle.getCycleSegments());
        }
    }

    /**
     * Identifies circular dependencies in which this package participates
     * using depth-first search.
     *
     * @param javaPackage Java package to inspect for dependency cycles
     */
    private void findCircularDependencies(JavaPackage javaPackage) {
        // Setup a depth trace anchored at the given java package.
        List<JavaPackage> trace = newTrace(new ArrayList<JavaPackage>(), javaPackage);

        Set<JavaPackage> searched = new HashSet<>();
        searchDependencies(javaPackage, trace, searched);
    }

    /**
     * Generates a new trace using the previous one and a new element
     *
     * @param trace       old search trace
     * @param javaPackage package to add to the trace
     * @return new search trace
     */
    private List<JavaPackage> newTrace(List<JavaPackage> trace,
                                       JavaPackage javaPackage) {
        List<JavaPackage> newTrace = new ArrayList<>(trace);
        newTrace.add(javaPackage);
        return newTrace;
    }


    /**
     * Recursive depth-first search through dependency tree
     *
     * @param javaPackage java package being searched currently
     * @param trace       search trace
     * @param searched    set of java packages already searched
     */
    private void searchDependencies(JavaPackage javaPackage,
                                    List<JavaPackage> trace,
                                    Set<JavaPackage> searched) {
        if (!searched.contains(javaPackage)) {
            searched.add(javaPackage);
            for (JavaPackage dependency : javaPackage.getDependencies()) {
                if (trace.contains(dependency)) {
                    cycles.add(new DependencyCycle(trace, dependency));
                } else {
                    searchDependencies(dependency, newTrace(trace, dependency), searched);
                }
            }
        }
    }

    /**
     * Resolves import names of Java sources into imports of entities known
     * to this catalog. All other import names will be ignored.
     */
    private void resolveImports() {
        for (JavaPackage javaPackage : getPackages()) {
            Set<JavaPackage> dependencies = new HashSet<>();
            for (JavaSource source : javaPackage.getSources()) {
                Set<JavaEntity> imports = resolveImports(source);
                source.setImports(imports);
                dependencies.addAll(importedPackages(imports));
            }
            javaPackage.setDependencies(dependencies);
        }
    }

    /**
     * Produces a set of imported Java packages from the specified set of
     * Java source entities.
     *
     * @param imports list of imported Java source entities
     * @return list of imported Java packages
     */
    private Set<JavaPackage> importedPackages(Set<JavaEntity> imports) {
        Set<JavaPackage> packages = new HashSet<>();
        for (JavaEntity entity : imports) {
            packages.add(entity instanceof JavaPackage ? (JavaPackage) entity :
                                 ((JavaSource) entity).getPackage());
        }
        return packages;
    }

    /**
     * Resolves import names of the specified Java source into imports of
     * entities known to this catalog. All other import names will be ignored.
     *
     * @param source Java source
     * @return list of resolved imports
     */
    private Set<JavaEntity> resolveImports(JavaSource source) {
        Set<JavaEntity> imports = new HashSet<>();
        for (String importName : source.getImportNames()) {
            JavaEntity entity = importName.matches(WILDCARD) ?
                    getPackage(importName.replaceAll(WILDCARD, "")) :
                    getSource(importName);
            if (entity != null) {
                imports.add(entity);
            }
        }
        return imports;
    }

    /**
     * Returns either an existing or a newly created Java package.
     *
     * @param packageName Java package name
     * @return Java package
     */
    private JavaPackage getOrCreatePackage(String packageName) {
        JavaPackage javaPackage = packages.get(packageName);
        if (javaPackage == null) {
            javaPackage = new JavaPackage(packageName);
            packages.put(packageName, javaPackage);
        }
        return javaPackage;
    }

    /**
     * Returns either an existing or a newly created Java source.
     *
     * @param path Java source path
     * @return Java source
     */
    private JavaSource getOrCreateSource(String path) {
        String name = nameFromPath(path);
        JavaSource source = sources.get(name);
        if (source == null) {
            source = new JavaSource(name, path);
            sources.put(name, source);
        }
        return source;
    }

    /**
     * Extracts a fully qualified source class name from the given path.
     * <p/>
     * For now, this implementation assumes standard Maven source structure
     * and thus will look for start of package name under 'src/main/java/'.
     * If it will not find such a prefix, it will simply return the path as
     * the name.
     *
     * @param path source path
     * @return source name
     */
    private String nameFromPath(String path) {
        int i = path.indexOf(SRC_ROOT);
        String name = i < 0 ? path : path.substring(i + SRC_ROOT.length());
        return name.replaceAll("\\.java$", "").replace("/", ".");
    }

    /**
     * Processes the package declaration pragma for the given source.
     *
     * @param source      Java source
     * @param packageName Java package name
     */
    private void processPackageDeclaration(JavaSource source, String packageName) {
        JavaPackage javaPackage = getOrCreatePackage(packageName);
        source.setPackage(javaPackage);
        javaPackage.addSource(source);
    }

    /**
     * Processes the import pragma for the given source.
     *
     * @param source Java source
     * @param name   name of the Java entity being imported (class or package)
     */
    private void processImportStatement(JavaSource source, String name) {
        source.addImportName(name);
    }

    /**
     * Returns the collection of java sources.
     *
     * @return collection of java sources
     */
    public Collection<JavaSource> getSources() {
        return Collections.unmodifiableCollection(sources.values());
    }

    /**
     * Returns the Java source with the specified name.
     *
     * @param name Java source name
     * @return Java source
     */
    public JavaSource getSource(String name) {
        return sources.get(name);
    }

    /**
     * Returns the collection of all Java packages.
     *
     * @return collection of java packages
     */
    public Collection<JavaPackage> getPackages() {
        return Collections.unmodifiableCollection(packages.values());
    }

    /**
     * Returns the set of all Java package dependency cycles.
     *
     * @return set of dependency cycles
     */
    public Set<DependencyCycle> getCycles() {
        return Collections.unmodifiableSet(cycles);
    }

    /**
     * Returns the set of all Java package dependency cycle segments.
     *
     * @return set of dependency cycle segments
     */
    public Set<Dependency> getCycleSegments() {
        return Collections.unmodifiableSet(cycleSegments);
    }

    /**
     * Returns the set of dependency cycles which involve the specified package.
     *
     * @param javaPackage java package
     * @return set of dependency cycles
     */
    public Set<DependencyCycle> getPackageCycles(JavaPackage javaPackage) {
        Set<DependencyCycle> set = packageCycles.get(javaPackage);
        return Collections.unmodifiableSet(set == null ? new HashSet<DependencyCycle>() : set);
    }

    /**
     * Returns the set of dependency cycle segments which involve the specified package.
     *
     * @param javaPackage java package
     * @return set of dependency cycle segments
     */
    public Set<Dependency> getPackageCycleSegments(JavaPackage javaPackage) {
        Set<Dependency> set = packageCycleSegments.get(javaPackage);
        return Collections.unmodifiableSet(set == null ? new HashSet<Dependency>() : set);
    }

    /**
     * Returns the Java package with the specified name.
     *
     * @param name Java package name
     * @return Java package
     */
    public JavaPackage getPackage(String name) {
        return packages.get(name);
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("packages", packages.size())
                .add("sources", sources.size())
                .add("cycles", cycles.size())
                .add("cycleSegments", cycleSegments.size()).toString();
    }

}
