/*
 *  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.tools.ant.taskdefs.cvslib;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.AbstractCvsTask;
import org.apache.tools.ant.util.CollectionUtils;
import org.apache.tools.ant.util.DOMElementWriter;
import org.apache.tools.ant.util.DOMUtils;
import org.apache.tools.ant.util.FileUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Examines the output of cvs rdiff between two tags.
 *
 * It produces an XML output representing the list of changes.
 * <pre>
 * &lt;!-- Root element --&gt;
 * &lt;!ELEMENT tagdiff (entry+) &gt;
 * &lt;!-- Start tag of the report --&gt;
 * &lt;!ATTLIST tagdiff startTag NMTOKEN #IMPLIED &gt;
 * &lt;!-- End tag of the report --&gt;
 * &lt;!ATTLIST tagdiff endTag NMTOKEN #IMPLIED &gt;
 * &lt;!-- Start date of the report --&gt;
 * &lt;!ATTLIST tagdiff startDate NMTOKEN #IMPLIED &gt;
 * &lt;!-- End date of the report --&gt;
 * &lt;!ATTLIST tagdiff endDate NMTOKEN #IMPLIED &gt;
 *
 * &lt;!-- CVS tag entry --&gt;
 * &lt;!ELEMENT entry (file) &gt;
 * &lt;!-- File added, changed or removed --&gt;
 * &lt;!ELEMENT file (name, revision?, prevrevision?) &gt;
 * &lt;!-- Name of the file --&gt;
 * &lt;!ELEMENT name (#PCDATA) &gt;
 * &lt;!-- Revision number --&gt;
 * &lt;!ELEMENT revision (#PCDATA) &gt;
 * &lt;!-- Previous revision number --&gt;
 * &lt;!ELEMENT prevrevision (#PCDATA) &gt;
 * </pre>
 *
 * @since Ant 1.5
 * @ant.task name="cvstagdiff"
 */
public class CvsTagDiff extends AbstractCvsTask {

    /**
     * Used to create the temp file for cvs log
     */
    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

    /** stateless helper for writing the XML document */
    private static final DOMElementWriter DOM_WRITER = new DOMElementWriter();

    /**
     * Token to identify the word file in the rdiff log
     */
    static final String FILE_STRING = "File ";
    /**
     * Length of token to identify the word file in the rdiff log
     */
    static final int FILE_STRING_LENGTH = FILE_STRING.length();
    /**
     * Token to identify the word file in the rdiff log
     */
    static final String TO_STRING = " to ";
    /**
     * Token to identify a new file in the rdiff log
     */
    static final String FILE_IS_NEW = " is new;";
    /**
     * Token to identify the revision
     */
    static final String REVISION = "revision ";

    /**
     * Token to identify a modified file in the rdiff log
     */
    static final String FILE_HAS_CHANGED = " changed from revision ";

    /**
     * Token to identify a removed file in the rdiff log
     */
    static final String FILE_WAS_REMOVED = " is removed";

    /**
     * The cvs package/module to analyse
     */
    private String mypackage;

    /**
     * The earliest tag from which diffs are to be included in the report.
     */
    private String mystartTag;

    /**
     * The latest tag from which diffs are to be included in the report.
     */
    private String myendTag;

    /**
     * The earliest date from which diffs are to be included in the report.
     */
    private String mystartDate;

    /**
     * The latest date from which diffs are to be included in the report.
     */
    private String myendDate;

    /**
     * The file in which to write the diff report.
     */
    private File mydestfile;

    /**
     * Used to skip over removed files
     */
    private boolean ignoreRemoved = false;

    /**
     * temporary list of package names.
     */
    private List packageNames = new ArrayList();

    /**
     * temporary list of "File:" + package name + "/" for all packages.
     */
    private String[] packageNamePrefixes = null;

    /**
     * temporary list of length values for prefixes.
     */
    private int[] packageNamePrefixLengths = null;

    /**
     * The package/module to analyze.
     * @param p the name of the package to analyse
     */
    @Override
    public void setPackage(String p) {
        mypackage = p;
    }

    /**
     * Set the start tag.
     *
     * @param s the start tag.
     */
    public void setStartTag(String s) {
        mystartTag = s;
    }

    /**
     * Set the start date.
     *
     * @param s the start date.
     */
    public void setStartDate(String s) {
        mystartDate = s;
    }

    /**
     * Set the end tag.
     *
     * @param s the end tag.
     */
    public void setEndTag(String s) {
        myendTag = s;
    }

    /**
     * Set the end date.
     *
     * @param s the end date.
     */
    public void setEndDate(String s) {
        myendDate = s;
    }

    /**
     * Set the output file for the diff.
     *
     * @param f the output file for the diff.
     */
    public void setDestFile(File f) {
        mydestfile = f;
    }

    /**
     * Set the ignore removed indicator.
     *
     * @param b the ignore removed indicator.
     *
     * @since Ant 1.8.0
     */
    public void setIgnoreRemoved(boolean b) {
        ignoreRemoved = b;
    }


    /**
     * Execute task.
     *
     * @exception BuildException if an error occurs
     */
    @Override
    public void execute() throws BuildException {
        // validate the input parameters
        validate();

        // build the rdiff command
        addCommandArgument("rdiff");
        addCommandArgument("-s");
        if (mystartTag != null) {
            addCommandArgument("-r");
            addCommandArgument(mystartTag);
        } else {
            addCommandArgument("-D");
            addCommandArgument(mystartDate);
        }
        if (myendTag != null) {
            addCommandArgument("-r");
            addCommandArgument(myendTag);
        } else {
            addCommandArgument("-D");
            addCommandArgument(myendDate);
        }

        // force command not to be null
        setCommand("");
        File tmpFile = null;
        try {
            handlePackageNames();

            tmpFile = FILE_UTILS.createTempFile(getProject(), "cvstagdiff", ".log", null,
                                                true, true);
            setOutput(tmpFile);

            // run the cvs command
            super.execute();

            // parse the rdiff
            CvsTagEntry[] entries = parseRDiff(tmpFile);

            // write the tag diff
            writeTagDiff(entries);

        } finally {
            packageNamePrefixes = null;
            packageNamePrefixLengths = null;
            packageNames.clear();
            if (tmpFile != null) {
                tmpFile.delete();
            }
        }
    }

    /**
     * Parse the tmpFile and return and array of CvsTagEntry to be
     * written in the output.
     *
     * @param tmpFile the File containing the output of the cvs rdiff command
     * @return the entries in the output
     * @exception BuildException if an error occurs
     */
    private CvsTagEntry[] parseRDiff(File tmpFile) throws BuildException {
        // parse the output of the command
        BufferedReader reader = null;

        try {
            reader = new BufferedReader(new FileReader(tmpFile)); //NOSONAR

            // entries are of the form:
            //CVS 1.11
            // File module/filename is new; current revision 1.1
            //CVS 1.11.9
            // File module/filename is new; cvstag_2003_11_03_2  revision 1.1
            // or
            // File module/filename changed from revision 1.4 to 1.6
            // or
            // File module/filename is removed; not included in
            // release tag SKINLF_12
            //CVS 1.11.9
            // File testantoine/antoine.bat is removed; TESTANTOINE_1 revision 1.1.1.1
            //
            // get rid of 'File module/"
            Vector entries = new Vector();

            String line = reader.readLine();

            while (null != line) {
                line = removePackageName(line, packageNamePrefixes,
                                         packageNamePrefixLengths);
                if (line != null) {
                    // use || in a perl like fashion
                    boolean processed
                        =  doFileIsNew(entries, line)
                        || doFileHasChanged(entries, line)
                        || doFileWasRemoved(entries, line);
                }
                line = reader.readLine();
            }

            CvsTagEntry[] array = new CvsTagEntry[entries.size()];
            entries.copyInto(array);

            return array;
        } catch (IOException e) {
            throw new BuildException("Error in parsing", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log(e.toString(), Project.MSG_ERR);
                }
            }
        }
    }

    private boolean doFileIsNew(Vector entries, String line) {
        int index = line.indexOf(FILE_IS_NEW);
        if (index == -1) {
            return false;
        }
        // it is a new file
        // set the revision but not the prevrevision
        String filename = line.substring(0, index);
        String rev = null;
        int indexrev = line.indexOf(REVISION, index);
        if (indexrev != -1) {
            rev = line.substring(indexrev + REVISION.length());
        }
        CvsTagEntry entry = new CvsTagEntry(filename, rev);
        entries.addElement(entry);
        log(entry.toString(), Project.MSG_VERBOSE);
        return true;
    }

    private boolean doFileHasChanged(Vector entries, String line) {
        int index = line.indexOf(FILE_HAS_CHANGED);
        if (index == -1) {
            return false;
        }
        // it is a modified file
        // set the revision and the prevrevision
        String filename = line.substring(0, index);
        int revSeparator = line.indexOf(" to ", index);
        String prevRevision =
            line.substring(index + FILE_HAS_CHANGED.length(),
                           revSeparator);
        String revision = line.substring(revSeparator + TO_STRING.length());
        CvsTagEntry entry = new CvsTagEntry(filename,
                                            revision,
                                            prevRevision);
        entries.addElement(entry);
        log(entry.toString(), Project.MSG_VERBOSE);
        return true;
    }

    private boolean doFileWasRemoved(Vector entries, String line) {
        if (ignoreRemoved) {
            return false;
        }
        int index = line.indexOf(FILE_WAS_REMOVED);
        if (index == -1) {
            return false;
        }
        // it is a removed file
        String filename = line.substring(0, index);
        String rev = null;
        int indexrev = line.indexOf(REVISION, index);
        if (indexrev != -1) {
            rev = line.substring(indexrev + REVISION.length());
        }
        CvsTagEntry entry = new CvsTagEntry(filename, null, rev);
        entries.addElement(entry);
        log(entry.toString(), Project.MSG_VERBOSE);
        return true;
    }

    /**
     * Write the rdiff log.
     *
     * @param entries a <code>CvsTagEntry[]</code> value
     * @exception BuildException if an error occurs
     */
    private void writeTagDiff(CvsTagEntry[] entries) throws BuildException {
        FileOutputStream output = null;
        try {
            output = new FileOutputStream(mydestfile);
            PrintWriter writer = new PrintWriter(
                                     new OutputStreamWriter(output, "UTF-8"));
            writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            Document doc = DOMUtils.newDocument();
            Element root = doc.createElement("tagdiff");
            if (mystartTag != null) {
                root.setAttribute("startTag", mystartTag);
            } else {
                root.setAttribute("startDate", mystartDate);
            }
            if (myendTag != null) {
                root.setAttribute("endTag", myendTag);
            } else {
                root.setAttribute("endDate", myendDate);
            }

            root.setAttribute("cvsroot", getCvsRoot());
            root.setAttribute("package",
                              CollectionUtils.flattenToString(packageNames));
            DOM_WRITER.openElement(root, writer, 0, "\t");
            writer.println();
            for (CvsTagEntry entry : entries) {
                writeTagEntry(doc, writer, entry);
            }
            DOM_WRITER.closeElement(root, writer, 0, "\t", true);
            writer.flush();
            if (writer.checkError()) {
                throw new IOException("Encountered an error writing tagdiff");
            }
            writer.close();
        } catch (UnsupportedEncodingException uee) {
            log(uee.toString(), Project.MSG_ERR);
        } catch (IOException ioe) {
            throw new BuildException(ioe.toString(), ioe);
        } finally {
            if (null != output) {
                try {
                    output.close();
                } catch (IOException ioe) {
                    log(ioe.toString(), Project.MSG_ERR);
                }
            }
        }
    }

    /**
     * Write a single entry to the given writer.
     *
     * @param doc Document used to create elements.
     * @param writer a <code>PrintWriter</code> value
     * @param entry a <code>CvsTagEntry</code> value
     */
    private void writeTagEntry(Document doc, PrintWriter writer,
                               CvsTagEntry entry)
        throws IOException {
        Element ent = doc.createElement("entry");
        Element f = DOMUtils.createChildElement(ent, "file");
        DOMUtils.appendCDATAElement(f, "name", entry.getFile());
        if (entry.getRevision() != null) {
            DOMUtils.appendTextElement(f, "revision", entry.getRevision());
        }
        if (entry.getPreviousRevision() != null) {
            DOMUtils.appendTextElement(f, "prevrevision",
                                       entry.getPreviousRevision());
        }
        DOM_WRITER.write(ent, writer, 1, "\t");
    }

    /**
     * Validate the parameters specified for task.
     *
     * @exception BuildException if a parameter is not correctly set
     */
    private void validate() throws BuildException {
        if (null == mypackage && getModules().size() == 0) {
            throw new BuildException("Package/module must be set.");
        }

        if (null == mydestfile) {
            throw new BuildException("Destfile must be set.");
        }

        if (null == mystartTag && null == mystartDate) {
            throw new BuildException("Start tag or start date must be set.");
        }

        if (null != mystartTag && null != mystartDate) {
            throw new BuildException("Only one of start tag and start date "
                                     + "must be set.");
        }

        if (null == myendTag && null == myendDate) {
            throw new BuildException("End tag or end date must be set.");
        }

        if (null != myendTag && null != myendDate) {
            throw new BuildException("Only one of end tag and end date must "
                                     + "be set.");
        }
    }

    /**
     * collects package names from the package attribute and nested
     * module elements.
     */
    private void handlePackageNames() {
        if (mypackage != null) {
            // support multiple packages
            StringTokenizer myTokenizer = new StringTokenizer(mypackage);
            while (myTokenizer.hasMoreTokens()) {
                String pack = myTokenizer.nextToken();
                packageNames.add(pack);
                addCommandArgument(pack);
            }
        }
        for (Iterator iter = getModules().iterator(); iter.hasNext();) {
            AbstractCvsTask.Module m = (AbstractCvsTask.Module) iter.next();
            packageNames.add(m.getName());
            // will be added to command line in super.execute()
        }
        packageNamePrefixes = new String[packageNames.size()];
        packageNamePrefixLengths = new int[packageNames.size()];
        for (int i = 0; i < packageNamePrefixes.length; i++) {
            packageNamePrefixes[i] = FILE_STRING + packageNames.get(i) + "/";
            packageNamePrefixLengths[i] = packageNamePrefixes[i].length();
        }
    }


    /**
     * removes a "File: module/" prefix if present.
     *
     * @return null if the line was shorter than expected.
     */
    private static String removePackageName(String line,
                                            String[] packagePrefixes,
                                            int[] prefixLengths) {
        if (line.length() < FILE_STRING_LENGTH) {
            return null;
        }
        boolean matched = false;
        for (int i = 0; i < packagePrefixes.length; i++) {
            if (line.startsWith(packagePrefixes[i])) {
                matched = true;
                line = line.substring(prefixLengths[i]);
                break;
            }
        }
        if (!matched) {
            line = line.substring(FILE_STRING_LENGTH);
        }
        return line;
    }
}
