 /*
 * 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.rat.anttasks;

 import org.apache.commons.io.IOUtils;
 import org.apache.rat.Defaults;
 import org.apache.rat.ReportConfiguration;
 import org.apache.rat.analysis.IHeaderMatcher;
 import org.apache.rat.analysis.util.HeaderMatcherMultiplexer;
 import org.apache.rat.api.RatException;
 import org.apache.rat.license.ILicenseFamily;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
 import org.apache.tools.ant.taskdefs.LogOutputStream;
 import org.apache.tools.ant.types.EnumeratedAttribute;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.ResourceCollection;
 import org.apache.tools.ant.types.resources.Union;
 import org.apache.tools.ant.util.FileUtils;

 import javax.xml.transform.TransformerException;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;

/**
 * A basic Ant task that generates a report on all files specified by
 * the nested resource collection(s).
 *
 * <p>IHeaderMatcher(s) can be specified as nested elements as well.</p>
 *
 * <p>The attribute <code>format</code> defines the output format and
 * can take the values
 * <ul>
 *   <li>xml - Rat's native XML output.</li>
 *   <li>styled - transforms the XML output using the given
 *   stylesheet.  The stylesheet attribute must be set as well if this
 *   attribute is used.</li>
 *   <li>plain - plain text using Rat's built-in stylesheet.  This is
 *   the default.</li>
 * </ul>
 */
public class Report extends Task {

    /**
     * will hold any nested resource collection
     */
    private Union nestedResources;
    /**
     * The licenses we want to match on.
     */
    private ArrayList<IHeaderMatcher> licenseMatchers = new ArrayList<IHeaderMatcher>();

    private ArrayList<ILicenseFamily> licenseNames = new ArrayList<ILicenseFamily>();

    /**
     * Whether to add the default list of license matchers.
     */
    private boolean addDefaultLicenseMatchers = true;
    /**
     * Where to send the report.
     */
    private File reportFile;
    /**
     * Which format to use.
     */
    private Format format = Format.PLAIN;
    /**
     * Which stylesheet to use.
     */
    private Resource stylesheet;
    /**
     * Whether to add license headers.
     */
    private AddLicenseHeaders addLicenseHeaders = new AddLicenseHeaders(AddLicenseHeaders.FALSE);
    /**
     * The copyright message.
     */
    private String copyrightMessage;

    /**
     * Adds resources that will be checked.
     * @param rc resource to check.
     */
    public void add(ResourceCollection rc) {
        if (nestedResources == null) {
            nestedResources = new Union();
        }
        nestedResources.add(rc);
    }

    /**
     * @param matcher Adds a license matcher.
     */
    public void add(IHeaderMatcher matcher) {
        licenseMatchers.add(matcher);
    }

    public void add(ILicenseFamily license) {
        licenseNames.add(license);
    }

    /**
     * @param addDefaultLicenseMatchers Whether to add the default list of license matchers.
     */
    public void setAddDefaultLicenseMatchers(boolean addDefaultLicenseMatchers) {
        this.addDefaultLicenseMatchers = addDefaultLicenseMatchers;
    }

    /**
     * Where to send the report to.
     * @param f report output file.
     */
    public void setReportFile(File f) {
        reportFile = f;
    }

    /**
     * Which format to use.
     * @param f format. 
     */
    public void setFormat(Format f) {
        if (f == null) {
            throw new IllegalArgumentException("format must not be null");
        }
        format = f;
    }

    /**
     * @param pAdd Whether to add license headers. 
     */
    public void setAddLicenseHeaders(AddLicenseHeaders pAdd) {
        if (pAdd == null) {
            throw new IllegalArgumentException("addLicenseHeaders must not be null");
        }
        addLicenseHeaders = pAdd;
    }

    /**
     * @param pMessage copyright message to set.
     */
    public void setCopyrightMessage(String pMessage) {
        copyrightMessage = pMessage;
    }
    
    /**
     * Which stylesheet to use (only meaningful with format='styled').
     * @param u stylesheet.
     */
    public void addConfiguredStylesheet(Union u) {
        if (stylesheet != null || u.size() != 1) {
            throw new BuildException("You must not specify more than one stylesheet.");
        }
        stylesheet = u.iterator().next();
    }

    /**
     * Generates the report.
     */
    @Override
    public void execute() {
        validate();

        PrintWriter out = null;
        try {
            if (reportFile == null) {
                out = new PrintWriter(
                          new OutputStreamWriter(
                              new LogOutputStream(this, Project.MSG_INFO)
                              )
                          );
            } else {
                out = new PrintWriter(new FileWriter(reportFile));
            }
            createReport(out);
            out.flush();
        } catch (IOException ioex) {
            throw new BuildException(ioex);
        } catch (TransformerException e) {
            throw new BuildException(e);
        } catch (InterruptedException e) {
            throw new BuildException(e);
        } catch (RatException e) {
            throw new BuildException(e);
        } finally {
            IOUtils.closeQuietly(out);
        }
    }

    /**
     * validates the task's configuration.
     */
    private void validate() {
        if (nestedResources == null) {
            throw new BuildException("You must specify at least one file to"
                                     + " create the report for.");
        }
        if (!addDefaultLicenseMatchers && licenseMatchers.size() == 0) {
            throw new BuildException("You must specify at least one license"
                                     + " matcher");
        }
        if (format.getValue().equals(Format.STYLED_KEY)) {
            if (stylesheet == null) {
                throw new BuildException("You must specify a stylesheet when"
                                         + " using the 'styled' format");
            }
            if (!stylesheet.isExists()) {
                throw new BuildException("Cannot find specified stylesheet '"
                                         + stylesheet + "'");
            }
        } else if (stylesheet != null) {
            log("Ignoring stylesheet '" + stylesheet + "' when using format '"
                + format.getValue() + "'", Project.MSG_WARN);
        }
    }

    /**
     * Writes the report to the given stream.
     * 
     * @param out stream to write report to.
     * 
     * @throws IOException in case of I/O errors.
     * @throws InterruptedException in case of threading errors.
     * @throws TransformerException in case of XML errors.
     * @throws RatException in case of general errors.
     */
    private void createReport(PrintWriter out) throws IOException, TransformerException, InterruptedException, RatException {
        final ReportConfiguration configuration = new ReportConfiguration();
        configuration.setHeaderMatcher(new HeaderMatcherMultiplexer(getLicenseMatchers()));
        configuration.setApprovedLicenseNames(getApprovedLicenseNames());
        configuration.setApproveDefaultLicenses(addDefaultLicenseMatchers);
        
        if (AddLicenseHeaders.FORCED.equalsIgnoreCase(addLicenseHeaders.getValue())) {
            configuration.setAddingLicenses(true);
            configuration.setAddingLicensesForced(true);
            configuration.setCopyrightMessage(copyrightMessage);
        } else if (AddLicenseHeaders.TRUE.equalsIgnoreCase(addLicenseHeaders.getValue())) {
            configuration.setAddingLicenses(true);
            configuration.setCopyrightMessage(copyrightMessage);
        } else if (!AddLicenseHeaders.FALSE.equalsIgnoreCase(addLicenseHeaders.getValue())) {
            throw new BuildException("Invalid value for addLicenseHeaders: " + addLicenseHeaders.getValue());
        }
        ResourceCollectionContainer rcElement = new ResourceCollectionContainer(nestedResources);
        if (format.getValue().equals(Format.XML_KEY)) {
            org.apache.rat.Report.report(rcElement, out, configuration);
        } else {
            InputStream style = null;
            try {
                if (format.getValue().equals(Format.PLAIN_KEY)) {
                    style = Defaults.getPlainStyleSheet();
                } else if (format.getValue().equals(Format.STYLED_KEY)) {
                    style = stylesheet.getInputStream();
                } else {
                    throw new BuildException("unsupported format '"
                                             + format.getValue() + "'");
                }
                org.apache.rat.Report.report(out, rcElement, style,
                                             configuration);
            } finally {
                FileUtils.close(style);
            }
        }
    }

    /**
     * Flattens all nested matchers plus the default matchers (if
     * required) into a single array.
     */
    private List<IHeaderMatcher> getLicenseMatchers() {
        List<IHeaderMatcher> matchers = new ArrayList<IHeaderMatcher>(Defaults.DEFAULT_MATCHERS);
        if (addDefaultLicenseMatchers) {
            int nestedSize = licenseMatchers.size();
            if (nestedSize != 0) {
                matchers.addAll(licenseMatchers);
            }
        } else {
            matchers = new ArrayList<IHeaderMatcher>();
        }
        return matchers;
    }

    private ILicenseFamily[] getApprovedLicenseNames() {
        // TODO: add support for adding default licenses
        ILicenseFamily[] results = null;
        if (licenseNames.size() > 0) {
            results = licenseNames.toArray(new ILicenseFamily[0]);
        }
        return results;
    }

    /**
     * Type for the format attribute.
     */
    public static class Format extends EnumeratedAttribute {
        static final String XML_KEY = "xml";
        static final String STYLED_KEY = "styled";
        static final String PLAIN_KEY = "plain";

        static final Format PLAIN = new Format(PLAIN_KEY);

        public Format() { super(); }

        private Format(String s) {
            this();
            setValue(s);
        }

        @Override
        public String[] getValues() {
            return new String[] {
                XML_KEY, STYLED_KEY, PLAIN_KEY
            };
        }
    }

    /**
     * Type for the addLicenseHeaders attribute.
     */
    public static class AddLicenseHeaders extends EnumeratedAttribute {
        static final String TRUE = "true";
        static final String FALSE = "false";
        static final String FORCED = "forced";

        public AddLicenseHeaders() {}
        public AddLicenseHeaders(String s) {
            setValue(s);
        }
        
        @Override
        public String[] getValues() {
            return new String[] {
                TRUE, FALSE, FORCED
            };
        }
    }
}
