/*
 *  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
 *
 *      https://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.ivy.ant;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.apache.ivy.core.cache.ArtifactOrigin;
import org.apache.ivy.core.cache.RepositoryCacheManager;
import org.apache.ivy.core.module.descriptor.Artifact;
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.resolve.IvyNode;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.retrieve.RetrieveOptions;
import org.apache.ivy.util.XMLHelper;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import static org.apache.ivy.util.StringUtils.splitToArray;

/**
 * Generates a report of all artifacts involved during the last resolve.
 */
public class IvyArtifactReport extends IvyPostResolveTask {
    private File tofile;

    private String pattern;

    public File getTofile() {
        return tofile;
    }

    public void setTofile(File aFile) {
        tofile = aFile;
    }

    public String getPattern() {
        return pattern;
    }

    public void setPattern(String aPattern) {
        pattern = aPattern;
    }

    public void doExecute() throws BuildException {
        prepareAndCheck();
        if (tofile == null) {
            throw new BuildException(
                    "no destination file name: please provide it through parameter 'tofile'");
        }

        pattern = getProperty(pattern, getSettings(), "ivy.retrieve.pattern");

        try {
            String[] confs = splitToArray(getConf());
            ModuleDescriptor md = null;
            if (getResolveId() == null) {
                md = getResolvedDescriptor(getOrganisation(), getModule(), false);
            } else {
                md = getResolvedDescriptor(getResolveId());
            }
            IvyNode[] dependencies = getIvyInstance().getResolveEngine().getDependencies(md,
                ((ResolveOptions) new ResolveOptions().setLog(getLog())).setConfs(confs)
                        .setResolveId(getResolveId()).setValidate(doValidate(getSettings())), null);

            Map<ArtifactDownloadReport, Set<String>> artifactsToCopy = getIvyInstance().getRetrieveEngine()
                    .determineArtifactsToCopy(ModuleRevisionId.newInstance(getOrganisation(),
                            getModule(), getRevision()), pattern,
                            ((RetrieveOptions) new RetrieveOptions().setLog(getLog()))
                                    .setConfs(confs).setResolveId(getResolveId()));

            Map<ModuleRevisionId, Set<ArtifactDownloadReport>> moduleRevToArtifactsMap = new HashMap<>();
            for (ArtifactDownloadReport artifact : artifactsToCopy.keySet()) {
                Set<ArtifactDownloadReport> moduleRevArtifacts = moduleRevToArtifactsMap.get(artifact.getArtifact()
                        .getModuleRevisionId());
                if (moduleRevArtifacts == null) {
                    moduleRevArtifacts = new HashSet<>();
                    moduleRevToArtifactsMap.put(artifact.getArtifact().getModuleRevisionId(),
                        moduleRevArtifacts);
                }
                moduleRevArtifacts.add(artifact);
            }

            generateXml(dependencies, moduleRevToArtifactsMap, artifactsToCopy);
        } catch (ParseException e) {
            log(e.getMessage(), Project.MSG_ERR);
            throw new BuildException("syntax errors in ivy file: " + e, e);
        } catch (IOException e) {
            throw new BuildException("impossible to generate report: " + e, e);
        }
    }

    private void generateXml(IvyNode[] dependencies,
                             Map<ModuleRevisionId, Set<ArtifactDownloadReport>> moduleRevToArtifactsMap,
                             Map<ArtifactDownloadReport, Set<String>> artifactsToCopy) {
        try {
            try (FileOutputStream fileOutputStream = new FileOutputStream(tofile)) {
                TransformerHandler saxHandler = createTransformerHandler(fileOutputStream);

                saxHandler.startDocument();
                saxHandler.startElement(null, "modules", "modules", new AttributesImpl());

                for (IvyNode dependency : dependencies) {
                    if (dependency.getModuleRevision() == null
                            || dependency.isCompletelyEvicted()) {
                        continue;
                    }

                    startModule(saxHandler, dependency);

                    Set<ArtifactDownloadReport> artifactsOfModuleRev = moduleRevToArtifactsMap.get(dependency
                            .getModuleRevision().getId());
                    if (artifactsOfModuleRev != null) {
                        for (ArtifactDownloadReport artifact : artifactsOfModuleRev) {

                            RepositoryCacheManager cache = dependency.getModuleRevision()
                                    .getArtifactResolver().getRepositoryCacheManager();

                            startArtifact(saxHandler, artifact.getArtifact());

                            writeOriginLocationIfPresent(cache, saxHandler, artifact);
                            writeCacheLocationIfPresent(cache, saxHandler, artifact);

                            for (String artifactDestPath : artifactsToCopy.get(artifact)) {
                                writeRetrieveLocation(saxHandler, artifactDestPath);
                            }
                            saxHandler.endElement(null, "artifact", "artifact");
                        }
                    }
                    saxHandler.endElement(null, "module", "module");
                }
                saxHandler.endElement(null, "modules", "modules");
                saxHandler.endDocument();
            }
        } catch (SAXException | IOException | TransformerConfigurationException e) {
            throw new BuildException("impossible to generate report", e);
        }
    }

    private TransformerHandler createTransformerHandler(FileOutputStream fileOutputStream)
            throws TransformerConfigurationException {
        TransformerHandler saxHandler = XMLHelper.getTransformerHandler();
        saxHandler.getTransformer().setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        saxHandler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");
        saxHandler.setResult(new StreamResult(fileOutputStream));
        return saxHandler;
    }

    private void startModule(TransformerHandler saxHandler, IvyNode dependency) throws SAXException {
        AttributesImpl moduleAttrs = new AttributesImpl();
        moduleAttrs.addAttribute(null, "organisation", "organisation", "CDATA", dependency
                .getModuleId().getOrganisation());
        moduleAttrs.addAttribute(null, "name", "name", "CDATA", dependency.getModuleId().getName());
        ResolvedModuleRevision moduleRevision = dependency.getModuleRevision();
        moduleAttrs.addAttribute(null, "rev", "rev", "CDATA", moduleRevision.getId().getRevision());
        moduleAttrs.addAttribute(null, "status", "status", "CDATA", moduleRevision.getDescriptor()
                .getStatus());
        saxHandler.startElement(null, "module", "module", moduleAttrs);
    }

    private void startArtifact(TransformerHandler saxHandler, Artifact artifact)
            throws SAXException {
        AttributesImpl artifactAttrs = new AttributesImpl();
        artifactAttrs.addAttribute(null, "name", "name", "CDATA", artifact.getName());
        artifactAttrs.addAttribute(null, "ext", "ext", "CDATA", artifact.getExt());
        artifactAttrs.addAttribute(null, "type", "type", "CDATA", artifact.getType());
        saxHandler.startElement(null, "artifact", "artifact", artifactAttrs);
    }

    private void writeOriginLocationIfPresent(RepositoryCacheManager cache,
            TransformerHandler saxHandler, ArtifactDownloadReport artifact) throws SAXException {
        ArtifactOrigin origin = artifact.getArtifactOrigin();
        if (!ArtifactOrigin.isUnknown(origin)) {
            String originName = origin.getLocation();
            boolean isOriginLocal = origin.isLocal();

            String originLocation;
            AttributesImpl originLocationAttrs = new AttributesImpl();
            if (isOriginLocal) {
                originLocationAttrs.addAttribute(null, "is-local", "is-local", "CDATA", "true");
                originLocation = originName.replace('\\', '/');
            } else {
                originLocationAttrs.addAttribute(null, "is-local", "is-local", "CDATA", "false");
                originLocation = originName;
            }
            saxHandler
                    .startElement(null, "origin-location", "origin-location", originLocationAttrs);
            char[] originLocationAsChars = originLocation.toCharArray();
            saxHandler.characters(originLocationAsChars, 0, originLocationAsChars.length);
            saxHandler.endElement(null, "origin-location", "origin-location");
        }
    }

    private void writeCacheLocationIfPresent(RepositoryCacheManager cache,
            TransformerHandler saxHandler, ArtifactDownloadReport artifact) throws SAXException {
        File archiveInCache = artifact.getLocalFile();

        if (archiveInCache != null) {
            saxHandler.startElement(null, "cache-location", "cache-location", new AttributesImpl());
            char[] archiveInCacheAsChars = archiveInCache.getPath().replace('\\', '/')
                    .toCharArray();
            saxHandler.characters(archiveInCacheAsChars, 0, archiveInCacheAsChars.length);
            saxHandler.endElement(null, "cache-location", "cache-location");
        }
    }

    private void writeRetrieveLocation(TransformerHandler saxHandler, String artifactDestPath)
            throws SAXException {
        artifactDestPath = removeLeadingPath(getProject().getBaseDir(), new File(artifactDestPath));

        saxHandler.startElement(null, "retrieve-location", "retrieve-location",
            new AttributesImpl());
        char[] artifactDestPathAsChars = artifactDestPath.replace('\\', '/').toCharArray();
        saxHandler.characters(artifactDestPathAsChars, 0, artifactDestPathAsChars.length);
        saxHandler.endElement(null, "retrieve-location", "retrieve-location");
    }

    // method largely inspired by ant 1.6.5 FileUtils method
    public String removeLeadingPath(File leading, File path) {
        String l = leading.getAbsolutePath();
        String p = path.getAbsolutePath();
        if (l.equals(p)) {
            return "";
        }

        // ensure that l ends with a /
        // so we never think /foo was a parent directory of /foobar
        if (!l.endsWith(File.separator)) {
            l += File.separator;
        }
        return (p.startsWith(l)) ? p.substring(l.length()) : p;
    }

}
