/*******************************************************************************
 * Copyright (c) 2008, 2012 Sonatype Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Sonatype Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.tycho.core.osgitools;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import org.eclipse.tycho.ArtifactDescriptor;
import org.eclipse.tycho.ArtifactKey;
import org.eclipse.tycho.ArtifactType;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.artifacts.DependencyArtifacts;
import org.eclipse.tycho.core.ArtifactDependencyVisitor;
import org.eclipse.tycho.core.ArtifactDependencyWalker;
import org.eclipse.tycho.core.PluginDescription;
import org.eclipse.tycho.core.resolver.shared.PlatformPropertiesUtils;
import org.eclipse.tycho.core.shared.TargetEnvironment;
import org.eclipse.tycho.model.Feature;
import org.eclipse.tycho.model.FeatureRef;
import org.eclipse.tycho.model.PluginRef;
import org.eclipse.tycho.model.ProductConfiguration;
import org.eclipse.tycho.model.UpdateSite;

public abstract class AbstractArtifactDependencyWalker implements ArtifactDependencyWalker {

    private final DependencyArtifacts artifacts;

    private final TargetEnvironment[] environments;

    public AbstractArtifactDependencyWalker(DependencyArtifacts artifacts) {
        this(artifacts, null);
    }

    public AbstractArtifactDependencyWalker(DependencyArtifacts artifacts, TargetEnvironment[] environments) {
        this.artifacts = artifacts;
        this.environments = environments;
    }

    @Override
    public void traverseUpdateSite(UpdateSite site, ArtifactDependencyVisitor visitor) {
        WalkbackPath visited = new WalkbackPath();

        for (FeatureRef ref : site.getFeatures()) {
            traverseFeature(ref, visitor, visited);
        }
    }

    @Override
    public void traverseFeature(File location, Feature feature, ArtifactDependencyVisitor visitor) {
        traverseFeature(location, feature, null, visitor, new WalkbackPath());
    }

    protected void traverseFeature(File location, Feature feature, FeatureRef featureRef,
            ArtifactDependencyVisitor visitor, WalkbackPath visited) {
        ArtifactDescriptor artifact = getArtifact(location, feature.getId());

        if (artifact == null) {
            // ah?
            throw new IllegalStateException("Feature " + location + " with id " + feature.getId()
                    + " is not part of the project build target platform");
        }

        ArtifactKey key = artifact.getKey();
        ReactorProject project = artifact.getMavenProject();
        String classifier = artifact.getClassifier();
        Set<Object> installableUnits = artifact.getInstallableUnits();

        DefaultFeatureDescription description = new DefaultFeatureDescription(key, location, project, classifier,
                feature, featureRef, installableUnits);

        if (visitor.visitFeature(description)) {
            for (PluginRef ref : feature.getPlugins()) {
                traversePlugin(ref, visitor, visited);
            }

            for (FeatureRef ref : feature.getIncludedFeatures()) {
                traverseFeature(ref, visitor, visited);
            }
        }
    }

    protected ArtifactDescriptor getArtifact(File location, String id) {
        Map<String, ArtifactDescriptor> artifacts = this.artifacts.getArtifact(location);
        if (artifacts != null) {
            for (ArtifactDescriptor artifact : artifacts.values()) {
                if (id.equals(artifact.getKey().getId())) {
                    return artifact;
                }
            }
        }
        return null;
    }

    @Override
    public void traverseProduct(ProductConfiguration product, ArtifactDependencyVisitor visitor) {
        traverseProduct(product, visitor, new WalkbackPath());
    }

    protected void traverseProduct(ProductConfiguration product, ArtifactDependencyVisitor visitor, WalkbackPath visited) {
        if (product.useFeatures()) {
            for (FeatureRef ref : product.getFeatures()) {
                traverseFeature(ref, visitor, visited);
            }
        } else {
            for (PluginRef ref : product.getPlugins()) {
                traversePlugin(ref, visitor, visited);
            }
        }

        Set<String> bundles = new HashSet<>();
        for (ArtifactDescriptor artifact : visited.getVisited()) {
            ArtifactKey key = artifact.getKey();
            if (ArtifactType.TYPE_ECLIPSE_PLUGIN.equals(key.getType())) {
                bundles.add(key.getId());
            }
        }

        if (environments != null && product.includeLaunchers()) {
            for (TargetEnvironment environment : environments) {
                String os = environment.getOs();
                String ws = environment.getWs();
                String arch = environment.getArch();

                String id;

                // for Mac OS X there is no org.eclipse.equinox.launcher.carbon.macosx.x86 or org.eclipse.equinox.launcher.carbon.macosx.ppc folder,
                // only a org.eclipse.equinox.launcher.carbon.macosx folder.
                // see http://jira.codehaus.org/browse/MNGECLIPSE-1075
                if (PlatformPropertiesUtils.OS_MACOSX.equals(os)
                        && (PlatformPropertiesUtils.ARCH_X86.equals(arch) || PlatformPropertiesUtils.ARCH_PPC
                                .equals(arch))) {
                    id = "org.eclipse.equinox.launcher." + ws + "." + os;
                } else {
                    id = "org.eclipse.equinox.launcher." + ws + "." + os + "." + arch;
                }

                if (!bundles.contains(id)) {
                    PluginRef ref = new PluginRef("plugin");
                    ref.setId(id);
                    ref.setOs(os);
                    ref.setWs(ws);
                    ref.setArch(arch);
                    ref.setUnpack(true);
                    traversePlugin(ref, visitor, visited);
                }
            }
        }
    }

    protected void traverseFeature(FeatureRef ref, ArtifactDependencyVisitor visitor, WalkbackPath visited) {
        ArtifactDescriptor artifact = artifacts.getArtifact(ArtifactType.TYPE_ECLIPSE_FEATURE, ref.getId(),
                ref.getVersion());

        if (artifact != null) {
            if (visited.visited(artifact.getKey())) {
                return;
            }

            visited.enter(artifact);
            try {
                File location = artifact.getLocation();

                Feature feature = Feature.loadFeature(location);
                traverseFeature(location, feature, ref, visitor, visited);
            } finally {
                visited.leave(artifact);
            }
        } else {
            visitor.missingFeature(ref, visited.getWalkback());
        }
    }

    private void traversePlugin(PluginRef ref, ArtifactDependencyVisitor visitor, WalkbackPath visited) {
        if (!matchTargetEnvironment(ref)) {
            return;
        }

        ArtifactDescriptor artifact = artifacts.getArtifact(ArtifactType.TYPE_ECLIPSE_PLUGIN, ref.getId(),
                ref.getVersion());

        if (artifact != null) {
            ArtifactKey key = artifact.getKey();
            if (visited.visited(key)) {
                return;
            }

            File location = artifact.getLocation();
            ReactorProject project = artifact.getMavenProject();
            String classifier = artifact.getClassifier();
            Set<Object> installableUnits = artifact.getInstallableUnits();

            PluginDescription description = new DefaultPluginDescription(key, location, project, classifier, ref,
                    installableUnits);
            visited.enter(description);
            try {
                visitor.visitPlugin(description);
            } finally {
                visited.leave(description);
            }
        } else {
            visitor.missingPlugin(ref, visited.getWalkback());
        }
    }

    private boolean matchTargetEnvironment(PluginRef pluginRef) {
        String pluginOs = pluginRef.getOs();
        String pluginWs = pluginRef.getWs();
        String pluginArch = pluginRef.getArch();

        if (environments == null) {
            // match all environments be default
            return true;

            // no target environments, only include environment independent plugins
            // return pluginOs == null && pluginWs == null && pluginArch == null;
        }

        for (TargetEnvironment environment : environments) {
            if (environment.match(pluginOs, pluginWs, pluginArch)) {
                return true;
            }
        }

        return false;
    }

    protected static class WalkbackPath {
        private Map<ArtifactKey, ArtifactDescriptor> visited = new HashMap<>();

        private Stack<ArtifactDescriptor> walkback = new Stack<>();

        boolean visited(ArtifactKey key) {
            return visited.containsKey(key);
        }

        public List<ArtifactDescriptor> getWalkback() {
            return new ArrayList<>(walkback);
        }

        void enter(ArtifactDescriptor artifact) {
            visited.put(artifact.getKey(), artifact);
            walkback.push(artifact);
        }

        void leave(ArtifactDescriptor artifact) {
            walkback.pop();
        }

        Collection<ArtifactDescriptor> getVisited() {
            return visited.values();
        }
    }
}
