/* ====================================================================
   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.poi.hpsf.examples;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.hpsf.HPSFRuntimeException;
import org.apache.poi.hpsf.MarkUnsupportedException;
import org.apache.poi.hpsf.MutablePropertySet;
import org.apache.poi.hpsf.NoPropertySetStreamException;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.Util;
import org.apache.poi.hpsf.WritingNotSupportedException;
import org.apache.poi.poifs.eventfilesystem.POIFSReader;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.Entry;
import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.TempFile;

/**
 * <p>This class copies a POI file system to a new file and compares the copy
 * with the original.</p>
 * 
 * <p>Property set streams are copied logically, i.e. the application
 * establishes a {@link org.apache.poi.hpsf.PropertySet} of an original property
 * set, creates a {@link org.apache.poi.hpsf.MutablePropertySet} from the
 * {@link org.apache.poi.hpsf.PropertySet} and writes the
 * {@link org.apache.poi.hpsf.MutablePropertySet} to the destination POI file
 * system. - Streams which are no property set streams are copied bit by
 * bit.</p>
 * 
 * <p>The comparison of the POI file systems is done logically. That means that
 * the two disk files containing the POI file systems do not need to be
 * exactly identical. However, both POI file systems must contain the same
 * files, and most of these files must be bitwise identical. Property set
 * streams, however, are compared logically: they must have the same sections
 * with the same attributs, and the sections must contain the same properties.
 * Details like the ordering of the properties do not matter.</p>
 */
public class CopyCompare
{
    /**
     * <p>Runs the example program. The application expects one or two
     * arguments:</p>
     * 
     * <ol>
     * 
     * <li><p>The first argument is the disk file name of the POI filesystem to
     * copy.</p></li>
     * 
     * <li><p>The second argument is optional. If it is given, it is the name of
     * a disk file the copy of the POI filesystem will be written to. If it is
     * not given, the copy will be written to a temporary file which will be
     * deleted at the end of the program.</p></li>
     * 
     * </ol>
     *
     * @param args Command-line arguments.
     * @exception MarkUnsupportedException if a POI document stream does not
     * support the mark() operation.
     * @exception NoPropertySetStreamException if the application tries to
     * create a property set from a POI document stream that is not a property
     * set stream.
     * @exception IOException if any I/O exception occurs.
     * @exception UnsupportedEncodingException if a character encoding is not
     * supported.
     */
    public static void main(final String[] args)
    throws NoPropertySetStreamException, MarkUnsupportedException,
           UnsupportedEncodingException, IOException
    {
        String originalFileName = null;
        String copyFileName = null;

        /* Check the command-line arguments. */
        if (args.length == 1) {
            originalFileName = args[0];
            File f = TempFile.createTempFile("CopyOfPOIFileSystem-", ".ole2");
            f.deleteOnExit();
            copyFileName = f.getAbsolutePath();
        } else if (args.length == 2) {
            originalFileName = args[0];
            copyFileName = args[1];
        } else {
            System.err.println("Usage: " + CopyCompare.class.getName() +
                               "originPOIFS [copyPOIFS]");
            System.exit(1);
        }

        /* Read the origin POIFS using the eventing API. The real work is done
         * in the class CopyFile which is registered here as a POIFSReader. */
        final POIFSReader r = new POIFSReader();
        final CopyFile cf = new CopyFile(copyFileName);
        r.registerListener(cf);
        FileInputStream fis = new FileInputStream(originalFileName);
        r.read(fis);
        fis.close();
        
        /* Write the new POIFS to disk. */
        cf.close();

        /* Read all documents from the original POI file system and compare them
         * with the equivalent document from the copy. */
        final POIFSFileSystem opfs = new POIFSFileSystem(new File(originalFileName));
        final POIFSFileSystem cpfs = new POIFSFileSystem(new File(copyFileName));

        final DirectoryEntry oRoot = opfs.getRoot();
        final DirectoryEntry cRoot = cpfs.getRoot();
        final StringBuffer messages = new StringBuffer();
        if (equal(oRoot, cRoot, messages)) {
            System.out.println("Equal");
        } else {
            System.out.println("Not equal: " + messages.toString());
        }
        cpfs.close();
        opfs.close();
    }



    /**
     * <p>Compares two {@link DirectoryEntry} instances of a POI file system.
     * The directories must contain the same streams with the same names and
     * contents.</p>
     *
     * @param d1 The first directory.
     * @param d2 The second directory.
     * @param msg The method may append human-readable comparison messages to
     * this string buffer. 
     * @return <code>true</code> if the directories are equal, else
     * <code>false</code>.
     * @exception MarkUnsupportedException if a POI document stream does not
     * support the mark() operation.
     * @exception NoPropertySetStreamException if the application tries to
     * create a property set from a POI document stream that is not a property
     * set stream.
     * @throws UnsupportedEncodingException 
     * @exception IOException if any I/O exception occurs.
     */
    private static boolean equal(final DirectoryEntry d1,
                                 final DirectoryEntry d2,
                                 final StringBuffer msg)
    throws NoPropertySetStreamException, MarkUnsupportedException,
           UnsupportedEncodingException, IOException
    {
        boolean equal = true;
        /* Iterate over d1 and compare each entry with its counterpart in d2. */
        for (final Entry e1 : d1) {
            final String n1 = e1.getName();
            Entry e2 = null;
            try {
                e2 = d2.getEntry(n1);
            } catch (FileNotFoundException ex) {
                msg.append("Document \"" + e1 + "\" exists, document \"" +
                           e2 + "\" does not.\n");
                equal = false;
                break;
            }

            if (e1.isDirectoryEntry() && e2.isDirectoryEntry()) {
                equal = equal((DirectoryEntry) e1, (DirectoryEntry) e2, msg);
            } else if (e1.isDocumentEntry() && e2.isDocumentEntry()) {
                equal = equal((DocumentEntry) e1, (DocumentEntry) e2, msg);
            } else {
                msg.append("One of \"" + e1 + "\" and \"" + e2 + "\" is a " +
                           "document while the other one is a directory.\n");
                equal = false;
            }
        }

        /* Iterate over d2 just to make sure that there are no entries in d2
         * that are not in d1. */
        for (final Entry e2 : d2) {
            final String n2 = e2.getName();
            Entry e1 = null;
            try {
                e1 = d1.getEntry(n2);
            } catch (FileNotFoundException ex) {
                msg.append("Document \"" + e2 + "\" exitsts, document \"" +
                           e1 + "\" does not.\n");
                equal = false;
                break;
            }
        }
        return equal;
    }



    /**
     * <p>Compares two {@link DocumentEntry} instances of a POI file system.
     * Documents that are not property set streams must be bitwise identical.
     * Property set streams must be logically equal.</p>
     *
     * @param d1 The first document.
     * @param d2 The second document.
     * @param msg The method may append human-readable comparison messages to
     * this string buffer. 
     * @return <code>true</code> if the documents are equal, else
     * <code>false</code>.
     * @exception MarkUnsupportedException if a POI document stream does not
     * support the mark() operation.
     * @exception NoPropertySetStreamException if the application tries to
     * create a property set from a POI document stream that is not a property
     * set stream.
     * @throws UnsupportedEncodingException 
     * @exception IOException if any I/O exception occurs.
     */
    private static boolean equal(final DocumentEntry d1, final DocumentEntry d2,
                                 final StringBuffer msg)
    throws NoPropertySetStreamException, MarkUnsupportedException,
           UnsupportedEncodingException, IOException
    {
        final DocumentInputStream dis1 = new DocumentInputStream(d1);
        final DocumentInputStream dis2 = new DocumentInputStream(d2);
        try {
            if (PropertySet.isPropertySetStream(dis1) &&
                PropertySet.isPropertySetStream(dis2)) {
                final PropertySet ps1 = PropertySetFactory.create(dis1);
                final PropertySet ps2 = PropertySetFactory.create(dis2);
                if (!ps1.equals(ps2)) {
                    msg.append("Property sets are not equal.\n");
                    return false;
                }
            } else {
                int i1, i2;
                do {
                    i1 = dis1.read();
                    i2 = dis2.read();
                    if (i1 != i2) {
                        msg.append("Documents are not equal.\n");
                        return false;
                    }
                } while (i1 > -1);
            }
        } finally {
            dis2.close();
            dis1.close();
        }
        return true;
    }



    /**
     * <p>This class does all the work. Its method {@link
     * #processPOIFSReaderEvent(POIFSReaderEvent)} is called for each file in
     * the original POI file system. Except for property set streams it copies
     * everything unmodified to the destination POI filesystem. Property set
     * streams are copied by creating a new {@link PropertySet} from the
     * original property set by using the {@link
     * MutablePropertySet#MutablePropertySet(PropertySet)} constructor.</p>
     */
    static class CopyFile implements POIFSReaderListener {
        private String dstName;
        private OutputStream out;
        private POIFSFileSystem poiFs;


        /**
         * <p>The constructor of a {@link CopyFile} instance creates the target
         * POIFS. It also stores the name of the file the POIFS will be written
         * to once it is complete.</p>
         * 
         * @param dstName The name of the disk file the destination POIFS is to
         * be written to.
         */
        public CopyFile(final String dstName) {
            this.dstName = dstName;
            poiFs = new POIFSFileSystem();
        }


        /**
         * <p>The method is called by POI's eventing API for each file in the
         * origin POIFS.</p>
         */
        @Override
        public void processPOIFSReaderEvent(final POIFSReaderEvent event) {
            /* The following declarations are shortcuts for accessing the
             * "event" object. */
            final POIFSDocumentPath path = event.getPath();
            final String name = event.getName();
            final DocumentInputStream stream = event.getStream();

            Throwable t = null;

            try {
                /* Find out whether the current document is a property set
                 * stream or not. */
                if (PropertySet.isPropertySetStream(stream)) {
                    /* Yes, the current document is a property set stream.
                     * Let's create a PropertySet instance from it. */
                    PropertySet ps = null;
                    try {
                        ps = PropertySetFactory.create(stream);
                    } catch (NoPropertySetStreamException ex) {
                        /* This exception will not be thrown because we already
                         * checked above. */
                    }

                    /* Copy the property set to the destination POI file
                     * system. */
                    copy(poiFs, path, name, ps);
                } else {
                    /* No, the current document is not a property set stream. We
                     * copy it unmodified to the destination POIFS. */
                    copy(poiFs, event.getPath(), event.getName(), stream);
                }
            } catch (MarkUnsupportedException ex) {
                t = ex;
            } catch (IOException ex) {
                t = ex;
            } catch (WritingNotSupportedException ex) {
                t = ex;
            }

            /* According to the definition of the processPOIFSReaderEvent method
             * we cannot pass checked exceptions to the caller. The following
             * lines check whether a checked exception occured and throws an
             * unchecked exception. The message of that exception is that of
             * the underlying checked exception. */
            if (t != null) {
                throw new HPSFRuntimeException
                    ("Could not read file \"" + path + "/" + name +
                     "\". Reason: " + Util.toString(t));
            }
        }



        /**
         * <p>Writes a {@link PropertySet} to a POI filesystem.</p>
         *
         * @param poiFs The POI filesystem to write to.
         * @param path The file's path in the POI filesystem.
         * @param name The file's name in the POI filesystem.
         * @param ps The property set to write.
         * @throws WritingNotSupportedException 
         * @throws IOException 
         */
        public void copy(final POIFSFileSystem poiFs,
                         final POIFSDocumentPath path,
                         final String name,
                         final PropertySet ps)
        throws WritingNotSupportedException, IOException {
            final DirectoryEntry de = getPath(poiFs, path);
            final MutablePropertySet mps = new MutablePropertySet(ps);
            de.createDocument(name, mps.toInputStream());
        }



        /**
         * <p>Copies the bytes from a {@link DocumentInputStream} to a new
         * stream in a POI filesystem.</p>
         *
         * @param poiFs The POI filesystem to write to.
         * @param path The source document's path.
         * @param name The source document's name.
         * @param stream The stream containing the source document.
         * @throws IOException 
         */
        public void copy(final POIFSFileSystem poiFs,
                         final POIFSDocumentPath path,
                         final String name,
                         final DocumentInputStream stream)
        throws IOException {
            final DirectoryEntry de = getPath(poiFs, path);
            final ByteArrayOutputStream out = new ByteArrayOutputStream();
            int c;
            while ((c = stream.read()) != -1) {
                out.write(c);
            }
            stream.close();
            out.close();
            final InputStream in =
                new ByteArrayInputStream(out.toByteArray());
            de.createDocument(name, in);
        }


        /**
         * <p>Writes the POI file system to a disk file.</p>
         *
         * @throws FileNotFoundException
         * @throws IOException
         */
        public void close() throws FileNotFoundException, IOException {
            out = new FileOutputStream(dstName);
            poiFs.writeFilesystem(out);
            out.close();
        }



        /** Contains the directory paths that have already been created in the
         * output POI filesystem and maps them to their corresponding
         * {@link org.apache.poi.poifs.filesystem.DirectoryNode}s. */
        private final Map<String,DirectoryEntry> paths = new HashMap<String,DirectoryEntry>();



        /**
         * <p>Ensures that the directory hierarchy for a document in a POI
         * fileystem is in place. When a document is to be created somewhere in
         * a POI filesystem its directory must be created first. This method
         * creates all directories between the POI filesystem root and the
         * directory the document should belong to which do not yet exist.</p>
         * 
         * <p>Unfortunately POI does not offer a simple method to interrogate
         * the POIFS whether a certain child node (file or directory) exists in
         * a directory. However, since we always start with an empty POIFS which
         * contains the root directory only and since each directory in the
         * POIFS is created by this method we can maintain the POIFS's directory
         * hierarchy ourselves: The {@link DirectoryEntry} of each directory
         * created is stored in a {@link Map}. The directories' path names map
         * to the corresponding {@link DirectoryEntry} instances.</p>
         *
         * @param poiFs The POI filesystem the directory hierarchy is created
         * in, if needed.
         * @param path The document's path. This method creates those directory
         * components of this hierarchy which do not yet exist.
         * @return The directory entry of the document path's parent. The caller
         * should use this {@link DirectoryEntry} to create documents in it.
         */
        public DirectoryEntry getPath(final POIFSFileSystem poiFs,
                                      final POIFSDocumentPath path) {
            try {
                /* Check whether this directory has already been created. */
                final String s = path.toString();
                DirectoryEntry de = paths.get(s);
                if (de != null)
                    /* Yes: return the corresponding DirectoryEntry. */
                    return de;

                /* No: We have to create the directory - or return the root's
                 * DirectoryEntry. */
                int l = path.length();
                if (l == 0) {
                    /* Get the root directory. It does not have to be created
                     * since it always exists in a POIFS. */
                    de = poiFs.getRoot();
                } else {
                    /* Create a subordinate directory. The first step is to
                     * ensure that the parent directory exists: */
                    de = getPath(poiFs, path.getParent());
                    /* Now create the target directory: */
                    de = de.createDirectory(path.getComponent
                                            (path.length() - 1));
                }
                paths.put(s, de);
                return de;
            } catch (IOException ex) {
                /* This exception will be thrown if the directory already
                 * exists. However, since we have full control about directory
                 * creation we can ensure that this will never happen. */
                ex.printStackTrace(System.err);
                throw new RuntimeException(ex.toString());
                /* FIXME (2): Replace the previous line by the following once we
                 * no longer need JDK 1.3 compatibility. */
                // throw new RuntimeException(ex);
            }
        }
    }

}
