/*
 * 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.geronimo.gshell.artifact.ivy;

import org.apache.geronimo.gshell.artifact.Artifact;
import org.apache.geronimo.gshell.artifact.ArtifactResolver;
import org.apache.geronimo.gshell.artifact.transfer.TransferListener;
import org.apache.ivy.Ivy;
import org.apache.ivy.core.module.descriptor.Configuration;
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.util.filter.Filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedHashSet;

/**
 * <a href="http://ant.apache.org/ivy">Apache Ivy</a> based {@link ArtifactResolver}.
 *
 * @version $Rev$ $Date$
 */
public class ArtifactResolverImpl
    implements ArtifactResolver
{
    private final Logger log = LoggerFactory.getLogger(getClass());

    private final Ivy ivy;

    public ArtifactResolverImpl(final Ivy ivy) {
        assert ivy != null;

        this.ivy = ivy;
    }

    public void setTransferListener(final TransferListener listener) {
        assert listener != null;
        
        // TODO: Figure out how to adapt/install into Ivy
    }

    public Result resolve(final Request request) throws Failure {
        assert request != null;

        ResolveOptions options = new ResolveOptions();
        options.setOutputReport(true);
        options.setTransitive(true);

        AndArtifactFilter filter = new AndArtifactFilter();
        options.setArtifactFilter(filter);

        // Filter deps needed for use of apache-ivy
        filter.add(new IvyDependenciesFilter());

        if (request.filter != null) {
            log.debug("Filter: {}", request.filter);

            filter.add(new Filter() {
                public boolean accept(final Object obj) {
                    if (!(obj instanceof org.apache.ivy.core.module.descriptor.Artifact)) {
                        return false;
                    }

                    Artifact artifact = createArtifact((org.apache.ivy.core.module.descriptor.Artifact)obj);
                    return request.filter.accept(artifact);
                }
            });
        }

        ModuleDescriptor md = createModuleDescriptor(request);

        Result result = new Result();

        try {
            ResolveReport resolveReport = ivy.resolve(md, options);
            result.artifacts = new LinkedHashSet<Artifact>();

            log.debug("Resolved:");

            for (ArtifactDownloadReport downloadReport : resolveReport.getAllArtifactsReports()) {
                Artifact artifact = createArtifact(downloadReport.getArtifact());
                artifact.setFile(downloadReport.getLocalFile());

                log.debug("    {}", artifact);

                result.artifacts.add(artifact);
            }
        }
        catch (Exception e) {
            throw new Failure(e);
        }

        return result;
    }

    private Artifact createArtifact(final org.apache.ivy.core.module.descriptor.Artifact source) {
        assert source != null;

        ModuleRevisionId sourceId = source.getModuleRevisionId();

        Artifact artifact = new Artifact();
        artifact.setGroup(sourceId.getOrganisation());
        artifact.setName(source.getName());
        artifact.setVersion(sourceId.getRevision());
        artifact.setType(source.getType());

        return artifact;
    }

    private ModuleDescriptor createModuleDescriptor(final Request request) {
        assert request != null;

        log.debug("Artifact: {}", request.artifact);

        ModuleRevisionId id = ModuleRevisionId.newInstance(request.artifact.getGroup(), request.artifact.getName(), request.artifact.getVersion());
        DefaultModuleDescriptor md = new DefaultModuleDescriptor(id, "integration", null, true);
        md.addConfiguration(new Configuration("default"));
        md.setLastModified(System.currentTimeMillis());

        if (request.artifacts != null) {
            log.debug("Dependencies:");

            for (Artifact artifact : request.artifacts) {
                log.debug("    {}", artifact);

                ModuleRevisionId depId = ModuleRevisionId.newInstance(artifact.getGroup(), artifact.getName(), artifact.getVersion());
                DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md, depId, false, false, true);
                dd.addDependencyConfiguration("default", "default");
                md.addDependency(dd);
            }
        }

        return md;
    }
}