/*
 *  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.TransformerFactoryConfigurationError;
import javax.xml.transform.sax.SAXTransformerFactory;
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.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 TransformerFactoryConfigurationError, TransformerConfigurationException {
        SAXTransformerFactory transformerFact = (SAXTransformerFactory) SAXTransformerFactory
                .newInstance();
        TransformerHandler saxHandler = transformerFact.newTransformerHandler();
        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;
    }

}
