/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.apache.ivyde.internal.eclipse.workspaceresolver;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.ivy.Ivy;
import org.apache.ivy.core.IvyContext;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.Configuration;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ExcludeRule;
import org.apache.ivy.core.module.descriptor.License;
import org.apache.ivy.core.module.descriptor.MDArtifact;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.DownloadReport;
import org.apache.ivy.core.report.DownloadStatus;
import org.apache.ivy.core.report.MetadataArtifactDownloadReport;
import org.apache.ivy.core.resolve.DownloadOptions;
import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.ManifestHeaderElement;
import org.apache.ivy.osgi.core.ManifestHeaderValue;
import org.apache.ivy.plugins.resolver.AbstractResolver;
import org.apache.ivy.plugins.resolver.util.ResolvedResource;
import org.apache.ivy.plugins.version.VersionMatcher;
import org.apache.ivy.util.Message;
import org.apache.ivyde.eclipse.cp.IvyClasspathContainer;
import org.apache.ivyde.eclipse.cp.IvyClasspathContainerHelper;
import org.apache.ivyde.internal.eclipse.IvyDEMessage;
import org.apache.ivyde.internal.eclipse.IvyPlugin;
import org.apache.ivyde.internal.eclipse.cpcontainer.IvyClasspathContainerImpl;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;

/**
 * This is an Eclipse workspace Ivy resolver. When used with the custom IvyClasspathContainer
 * changes, this resolver will link dependent projects when they are open in the same workspace,
 * allowing full-fledged linked project functionality Eclipse provides, such as incremental
 * compilation, debugging, mouseover javadocs, and source browsing across projects.
 * 
 * <b>How it works</b> During a resolve, it looks at all open projects in the workspace that have
 * Ivy containers. The <b>first</b> project that publishes the module on which the project being
 * resolved depends, will be picked and returned as a special type of artifact called "project".
 * 
 * The IvyClasspathContainer will recognize the artifact as a project and put the eclipse project as
 * a dependent project within the classpath container of the parent.
 * 
 * If you do not want a project to be linked as a dependency, close it or delete from the workspace.
 * As soon as you do that, any projects that were linked to it will automatically re-resolve (see
 * {@link WorkspaceResourceChangeListener}) and use the standard Ivy means of finding the
 * dependency.
 * 
 * The {@link WorkspaceResourceChangeListener} will also auto-resolve when a new project is added or
 * opened, so opening a project will automatically link it into the currently open projects where
 * necessary.
 * 
 * Since the resolver is not aware which module revision a project is publishing, it optimistically
 * matches any revision of the module.
 * 
 * Since the resolver stops after finding the first open project which matches the module, having
 * multiple open versions of the same project in the workspace (for example, different branches) may
 * set the wrong version as a dependency. You are advised to only open the version of the project
 * which you want other projects in the workspace to depend on.
 * 
 * NOTE: Transitive dependencies are not passed from the dependent project to the parent when
 * projects are linked. If you find you are missing some transitive dependencies, just set your
 * dependent eclipse project to export its ivy dependencies. (Project->Properties->Java Build
 * Path->Order and Export-> -> check the ivy container) This will only export the configuration that
 * project is using and not what a dependent project may ask for when it's being resolved. To do
 * that, this resolver will need to be modified to pass transitive dependencies along.
 */
public class WorkspaceResolver extends AbstractResolver {

    public static final String ECLIPSE_PROJECT_TYPE = "eclipse-project";

    public static final String ECLIPSE_PROJECT_EXTENSION = "eclipse-project";

    public static final String CACHE_NAME = "__ivyde-workspace-resolver-cache";

    public static final String IVYDE_WORKSPACE_ARTIFACTS = "IvyDEWorkspaceArtifacts";

    public static final String IVYDE_WORKSPACE_ARTIFACT_REPORTS = "IvyDEWorkspaceArtifactReports";

    private IProject[] projects;

    private boolean ignoreBranchOnWorkspaceProjects;

    private boolean ignoreVersionOnWorkspaceProjects;

    public WorkspaceResolver(IProject project, IvySettings ivySettings) {
        String projectName = project == null ? "<null>" : project.getName();
        setName(projectName + "-ivyde-workspace-resolver");
        setSettings(ivySettings);
        setCache(CACHE_NAME);

        projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();

        ignoreBranchOnWorkspaceProjects = IvyPlugin.getPreferenceStoreHelper()
                .getIgnoreBranchOnWorkspaceProjects();

        ignoreVersionOnWorkspaceProjects = IvyPlugin.getPreferenceStoreHelper()
                .getIgnoreVersionOnWorkspaceProjects();
    }

    public DownloadReport download(Artifact[] artifacts, DownloadOptions options) {
        IvyContext context = IvyContext.getContext();
        @SuppressWarnings("unchecked")
        Map<Artifact, Artifact> workspaceArtifacts = (Map<Artifact, Artifact>) context
                .get(IVYDE_WORKSPACE_ARTIFACTS);
        Map<Artifact, ArtifactDownloadReport> workspaceReports = null;
        if (workspaceArtifacts != null) {
            workspaceReports = new HashMap<Artifact, ArtifactDownloadReport>();
            context.set(IVYDE_WORKSPACE_ARTIFACT_REPORTS, workspaceReports);
        }

        // Not much to do here - downloads are not required for workspace projects.
        DownloadReport dr = new DownloadReport();
        for (int i = 0; i < artifacts.length; i++) {
            ArtifactDownloadReport adr = new ArtifactDownloadReport(artifacts[i]);
            dr.addArtifactReport(adr);
            // Only report java projects as downloaded
            if (artifacts[i].getType().equals(ECLIPSE_PROJECT_TYPE)) {
                adr.setDownloadStatus(DownloadStatus.NO);
                adr.setSize(0);
                Message.verbose("\t[IN WORKSPACE] " + artifacts[i]);
            } else if (workspaceArtifacts != null && workspaceArtifacts.containsKey(artifacts[i])) {
                adr.setDownloadStatus(DownloadStatus.NO);
                adr.setSize(0);
                // there is some 'forced' artifact by the dependency descriptor
                Artifact eclipseArtifact = (Artifact) workspaceArtifacts.get(artifacts[i]);
                ArtifactDownloadReport eclipseAdr = new ArtifactDownloadReport(eclipseArtifact);
                eclipseAdr.setDownloadStatus(DownloadStatus.NO);
                eclipseAdr.setSize(0);
                workspaceReports.put(artifacts[i], eclipseAdr);
                Message.verbose("\t[IN WORKSPACE] " + eclipseArtifact);
            } else {
                adr.setDownloadStatus(DownloadStatus.FAILED);
                Message.verbose("\t[Eclipse Workspace resolver] "
                        + "cannot download non-project artifact: " + artifacts[i]);
            }
        }
        return dr;
    }

    public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
            throws ParseException {
        IvyContext context = IvyContext.getContext();

        String contextId = "ivyde.workspaceresolver." + getName() + "."
                + dd.getDependencyRevisionId().toString();
        DependencyDescriptor parentDD = (DependencyDescriptor) context.get(contextId);
        if (parentDD != null
                && parentDD.getDependencyRevisionId().equals(dd.getDependencyRevisionId())) {
            // this very workspace resolver has been already called for the same dependency
            // we are going into a circular dependency, let's return 'not found'
            return null;
        }
        context.set(contextId, dd);

        ModuleRevisionId dependencyMrid = dd.getDependencyRevisionId();
        String org = dependencyMrid.getModuleId().getOrganisation();
        String module = dependencyMrid.getModuleId().getName();

        VersionMatcher versionMatcher = getSettings().getVersionMatcher();

        // Iterate over workspace to find Java project which has an Ivy
        // container for this dependency
        for (int i = 0; i < projects.length; i++) {
            IProject p = projects[i];
            if (!p.exists()) {
                continue;
            }
            List<IvyClasspathContainer> containers = IvyClasspathContainerHelper.getContainers(p);
            Iterator<IvyClasspathContainer> itContainer = containers.iterator();
            while (itContainer.hasNext()) {
                IvyClasspathContainerImpl ivycp = (IvyClasspathContainerImpl) itContainer.next();
                ModuleDescriptor md = ivycp.getState().getCachedModuleDescriptor();
                if (md == null) {
                    continue;
                }
                ModuleRevisionId candidateMrid = md.getModuleRevisionId();

                // search a match on the organization and the module name
                
                if (org.equals(BundleInfo.BUNDLE_TYPE)) {
                    // looking for an OSGi bundle via its symbolic name
                    String sn = (String) md.getExtraInfo().get("Bundle-SymbolicName");
                    if (sn == null || !module.equals(sn)) {
                        // not found, skip to next
                        continue;
                    }
                } else if (org.equals(BundleInfo.PACKAGE_TYPE)) {
                    // looking for an OSGi bundle via its exported package
                    String exportedPackages = (String) md.getExtraInfo().get("Export-Package");
                    if (exportedPackages == null) {
                        // not found, skip to next
                        continue;
                    }
                    boolean found = false;
                    String version = null;
                    ManifestHeaderValue exportElements = new ManifestHeaderValue(exportedPackages);
                    for (ManifestHeaderElement exportElement : exportElements.getElements()) {
                        if (exportElement.getValues().contains(module)) {
                            found = true;
                            version = exportElement.getAttributes().get("version");
                            break;
                        }
                    }
                    if (!found) {
                        // not found, skip to next
                        continue;
                    }
                    if (version == null) {
                        // no version means anything can match. Let's trick the version matcher by
                        // setting the exact expected version
                        version = dependencyMrid.getRevision();
                    }
                    md.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(org, module, version));
                } else {
                    if (!candidateMrid.getModuleId().equals(dependencyMrid.getModuleId())) {
                        // it doesn't match org#module, skip to next
                        continue;
                    }
                }

                IvyDEMessage.verbose("Workspace resolver found potential matching project "
                        + p.getName() + " with module " + candidateMrid + " for module "
                        + dependencyMrid);

                if (!ignoreBranchOnWorkspaceProjects) {
                    ModuleId mid = dependencyMrid.getModuleId();
                    String defaultBranch = getSettings().getDefaultBranch(mid);
                    String dependencyBranch = dependencyMrid.getBranch();
                    String candidateBranch = candidateMrid.getBranch();
                    if (dependencyBranch == null) {
                        dependencyBranch = defaultBranch;
                    }
                    if (candidateBranch == null) {
                        candidateBranch = defaultBranch;
                    }
                    if (dependencyBranch != candidateBranch) {
                        // Both cannot be null
                        if (dependencyBranch == null || candidateBranch == null) {
                            IvyDEMessage
                                    .verbose("\t\trejected since branches doesn't match (one is set, the other isn't)");
                            continue;
                        }
                        if (!dependencyBranch.equals(candidateBranch)) {
                            IvyDEMessage.verbose("\t\trejected since branches doesn't match");
                            continue;
                        }
                    }
                }

                // Found one; check if it is for the module we need
                if (ignoreVersionOnWorkspaceProjects
                        || md.getModuleRevisionId().getRevision().equals(Ivy.getWorkingRevision())
                        || versionMatcher.accept(dd.getDependencyRevisionId(), md)) {

                    if (ignoreVersionOnWorkspaceProjects) {
                        IvyDEMessage.verbose("\t\tmatched (version are ignored)");
                    } else {
                        IvyDEMessage.verbose("\t\tversion matched");
                    }

                    Artifact af = new DefaultArtifact(md.getModuleRevisionId(),
                            md.getPublicationDate(), p.getFullPath().toString(),
                            ECLIPSE_PROJECT_TYPE, ECLIPSE_PROJECT_EXTENSION);

                    DependencyArtifactDescriptor[] dArtifacts = dd.getAllDependencyArtifacts();
                    if (dArtifacts != null) {
                        // the dependency is declaring explicitely some artifacts to download
                        // we need to trick to and map these requested artifact by the Eclipse
                        // project

                        // we need the context which is used when downloading data, which is the
                        // parent
                        // of the current one
                        // so let's hack: popContext (the child), getContext (the parent), setVar,
                        // pushContext (child)
                        IvyContext currentContext = IvyContext.popContext();
                        IvyContext parentContext = IvyContext.getContext();
                        @SuppressWarnings("unchecked")
                        Map<Artifact, Artifact> workspaceArtifacts = (Map<Artifact, Artifact>) parentContext
                                .get(IVYDE_WORKSPACE_ARTIFACTS);
                        if (workspaceArtifacts == null) {
                            workspaceArtifacts = new HashMap<Artifact, Artifact>();
                            parentContext.set(IVYDE_WORKSPACE_ARTIFACTS, workspaceArtifacts);
                        }
                        for (int j = 0; j < dArtifacts.length; j++) {
                            Artifact artifact = new MDArtifact(md, dArtifacts[j].getName(),
                                    dArtifacts[j].getType(), dArtifacts[j].getExt(),
                                    dArtifacts[j].getUrl(),
                                    dArtifacts[j].getQualifiedExtraAttributes());
                            workspaceArtifacts.put(artifact, af);
                        }
                        IvyContext.pushContext(currentContext);
                    }

                    DefaultModuleDescriptor workspaceMd = cloneMd(md, af);

                    MetadataArtifactDownloadReport madr = new MetadataArtifactDownloadReport(af);
                    madr.setDownloadStatus(DownloadStatus.SUCCESSFUL);
                    madr.setSearched(true);

                    return new ResolvedModuleRevision(this, this, workspaceMd, madr);
                } else {
                    IvyDEMessage.verbose("\t\treject as version didn't match");
                }
            }
        }

        // Didn't find module in any open project, proceed to other resolvers.
        return null;
    }

    private DefaultModuleDescriptor cloneMd(ModuleDescriptor md, Artifact af) {

        DefaultModuleDescriptor newMd = new DefaultModuleDescriptor(md.getModuleRevisionId(),
                "release", null, true);
        newMd.addConfiguration(new Configuration(ModuleDescriptor.DEFAULT_CONFIGURATION));
        newMd.setLastModified(System.currentTimeMillis());

        newMd.setDescription(md.getDescription());
        newMd.setHomePage(md.getHomePage());
        newMd.setLastModified(md.getLastModified());
        newMd.setPublicationDate(md.getPublicationDate());
        newMd.setResolvedPublicationDate(md.getResolvedPublicationDate());
        newMd.setStatus(md.getStatus());

        Configuration[] allConfs = md.getConfigurations();
        if (allConfs.length == 0) {
            newMd.addArtifact(ModuleDescriptor.DEFAULT_CONFIGURATION, af);
        } else {
            for (int k = 0; k < allConfs.length; k++) {
                newMd.addConfiguration(allConfs[k]);
                newMd.addArtifact(allConfs[k].getName(), af);
            }
        }

        DependencyDescriptor[] dependencies = md.getDependencies();
        for (int k = 0; k < dependencies.length; k++) {
            newMd.addDependency(dependencies[k]);
        }

        ExcludeRule[] allExcludeRules = md.getAllExcludeRules();
        for (int k = 0; k < allExcludeRules.length; k++) {
            newMd.addExcludeRule(allExcludeRules[k]);
        }

        newMd.getExtraInfo().putAll(md.getExtraInfo());

        License[] licenses = md.getLicenses();
        for (int k = 0; k < licenses.length; k++) {
            newMd.addLicense(licenses[k]);
        }

        return newMd;
    }

    public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
        throw new UnsupportedOperationException("publish not supported by " + getName());
    }

    public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) {
        return null;
    }
}
