/*
 * ******************************************************************************
 * Copyright (C) 2007, International Business Machines Corporation and others.
 * All Rights Reserved.
 * ******************************************************************************
 */
package com.ibm.icu.dev.tool.tzu;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.MissingResourceException;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

/**
 * A class that represents an updatable ICU4J jar file. A file is an updatable
 * ICU4J jar file if it
 * <ul>
 * <li>exists</li>
 * <li>is a file (ie. not a directory)</li>
 * <li>does not end with .ear or .war (these file types are unsupported)</li>
 * <li>ends with .jar</li>
 * <li>is updatable according the <code>isUpdatable</code></li>
 * <li>is not signed.</li>
 * </ul>
 */
public class ICUFile {
    /**
     * ICU version to use if one cannot be found.
     */
    public static final String ICU_VERSION_UNKNOWN = "Unknown";

    /**
     * A directory entry that is found in every updatable ICU4J jar file.
     */
    public static final String TZ_ENTRY_DIR = "com/ibm/icu/impl";

    /**
     * Prefix of the timezone resource filename.
     */
    public static final String TZ_ENTRY_FILENAME_PREFIX = "zoneinfo";

    /**
     * Extension of the timezone resource filename.
     */
    public static final String TZ_ENTRY_FILENAME_EXTENSION = ".res";

    /**
     * The timezone resource filename.
     */
    public static final String TZ_ENTRY_FILENAME = TZ_ENTRY_FILENAME_PREFIX
            + TZ_ENTRY_FILENAME_EXTENSION;

    /**
     * Key to use when getting the version of a timezone resource.
     */
    public static final String TZ_VERSION_KEY = "TZVersion";

    /**
     * Timezone version to use if one cannot be found.
     */
    public static final String TZ_VERSION_UNKNOWN = "Unknown";

    /**
     * The buffer size to use for copying data.
     */
    private static final int BUFFER_SIZE = 1024;

    /**
     * Determines the version of a timezone resource as a standard file without
     * locking the file.
     * 
     * @param tzFile
     *            The file representing the timezone resource.
     * @param logger
     *            The current logger.
     * @return The version of the timezone resource.
     */
    public static String findFileTZVersion(File tzFile, Logger logger) {
        ICUFile rawTZFile = new ICUFile(logger);

        try {
            File temp = File.createTempFile("zoneinfo", ".res");
            temp.deleteOnExit();
            rawTZFile.copyFile(tzFile, temp);
            return findTZVersion(temp, logger);
        } catch (IOException ex) {
            logger.errorln(ex.getMessage());
            return null;
        }
    }

    /**
     * Determines the version of a timezone resource as a standard file, but
     * locks the file for the duration of the program.
     * 
     * @param tzFile
     *            The file representing the timezone resource.
     * @param logger
     *            The current logger.
     * @return The version of the timezone resource.
     */
    private static String findTZVersion(File tzFile, Logger logger) {
        try {
            String filename = tzFile.getName();
            String entryname = filename.substring(0, filename.length()
                    - ".res".length());

            URL url = new URL(tzFile.getAbsoluteFile().getParentFile().toURL()
                    .toString());
            ClassLoader loader = new URLClassLoader(new URL[] { url });

            // UResourceBundle bundle = UResourceBundle.getBundleInstance("",
            // entryname, loader);

            URL bundleURL = new URL(new File("icu4j.jar").toURL().toString());
            URLClassLoader bundleLoader = new URLClassLoader(
                    new URL[] { bundleURL });
            Class bundleClass = bundleLoader
                    .loadClass("com.ibm.icu.util.UResourceBundle");
            Method bundleGetInstance = bundleClass.getMethod(
                    "getBundleInstance", new Class[] { String.class,
                            String.class, ClassLoader.class });
            Object bundle = bundleGetInstance.invoke(null, new Object[] { "",
                    entryname, loader });

            if (bundle != null) {
                Method bundleGetString = bundleClass.getMethod("getString",
                        new Class[] { String.class });
                String tzVersion = (String) bundleGetString.invoke(bundle,
                        new Object[] { TZ_VERSION_KEY });
                if (tzVersion != null)
                    return tzVersion;
            }
        } catch (MalformedURLException ex) {
            // this should never happen
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            // this would most likely happen when UResourceBundle cannot be
            // resolved, which is when icu4j.jar is not where it should be
            logger.errorln("icu4j.jar not found");
        } catch (NoSuchMethodException ex) {
            // this can only be caused by a very unlikely scenario
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            // this can only be caused by a very unlikely scenario
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            // if this is holding a MissingResourceException, then this is not
            // an error -- some zoneinfo files do not have a version number
            if (!(ex.getTargetException() instanceof MissingResourceException))
                ex.printStackTrace();
        }

        return TZ_VERSION_UNKNOWN;
    }

    /**
     * Finds the jar entry in the jar file that represents a timezone resource
     * and returns it, or null if none is found.
     * 
     * @param jar
     *            The jar file to search.
     * @return The jar entry representing the timezone resource in the jar file,
     *         or null if none is found.
     */
    private static JarEntry getTZEntry(JarFile jar) {
        JarEntry tzEntry = null;
        Enumeration e = jar.entries();
        while (e.hasMoreElements()) {
            tzEntry = (JarEntry) e.nextElement();
            if (tzEntry.getName().endsWith(TZ_ENTRY_FILENAME))
                return tzEntry;
        }
        return null;
    }

    /**
     * The ICU4J jar file represented by this ICUFile.
     */
    private File icuFile;

    /**
     * The ICU version of the ICU4J jar.
     */
    private String icuVersion;

    /**
     * The current logger.
     */
    private Logger logger;

    /**
     * The entry for the timezone resource inside the ICU4J jar.
     */
    private JarEntry tzEntry;

    /**
     * The version of the timezone resource inside the ICU4J jar.
     */
    private String tzVersion;

    /**
     * Constructs an ICUFile around a file. See <code>initialize</code> for
     * details.
     * 
     * @param file
     *            The file to wrap this ICUFile around.
     * @param logger
     *            The current logger.
     * @throws IOException
     */
    public ICUFile(File file, Logger logger) throws IOException {
        initialize(file, logger);
    }

    /**
     * Constructs an ICUFile around a file. See <code>initialize</code> for
     * details.
     * 
     * @param filename
     *            The file to wrap this ICUFile around.
     * @param logger
     *            The current logger.
     * @throws IOException
     */
    public ICUFile(String filename, Logger logger) throws IOException {
        if (filename == null || filename.trim().length() == 0)
            throw new IOException("cannot be blank");

        initialize(new File(filename), logger);
    }

    /**
     * Constructs a blank ICUFile. Used internally for timezone resource files
     * that are not contained within a jar.
     * 
     * @param logger
     *            The current logger.
     */
    private ICUFile(Logger logger) {
        this.logger = logger;
    }

    /**
     * Compares two ICUFiles by the file they represent.
     * 
     * @param other
     *            The other ICUFile to compare to.
     * @return Whether the files represented by the two ICUFiles are equal.
     */
    public boolean equals(Object other) {
        return (!(other instanceof ICUFile)) ? false : icuFile
                .equals(((ICUFile) other).icuFile);
    }

    /**
     * Determines the version of a timezone resource in a jar file without
     * locking the jar file.
     * 
     * @return The version of the timezone resource.
     */
    public String findEntryTZVersion() {
        try {
            File temp = File.createTempFile("zoneinfo", ".res");
            temp.deleteOnExit();
            copyEntry(icuFile, tzEntry, temp);
            return findTZVersion(temp, logger);
        } catch (IOException ex) {
            logger.errorln(ex.getMessage());
            return null;
        }
    }

    /**
     * Returns the File object represented by this ICUFile object.
     * 
     * @return The File object represented by this ICUFile object.
     */
    public File getFile() {
        return icuFile;
    }

    /**
     * Returns the filename of this ICUFile object, without the path.
     * 
     * @return The filename of this ICUFile object, without the path.
     */
    public String getFilename() {
        return icuFile.getName();
    }

    /**
     * Returns the ICU version of this ICU4J jar.
     * 
     * @return The ICU version of this ICU4J jar.
     */
    public String getICUVersion() {
        return icuVersion;
    }

    /**
     * Returns the path of this ICUFile object, without the filename.
     * 
     * @return The path of this ICUFile object, without the filename.
     */
    public String getPath() {
        return icuFile.getAbsoluteFile().getParent();
    }

    // public static String findURLTZVersion(File tzFile) {
    // try {
    // File temp = File.createTempFile("zoneinfo", ".res");
    // temp.deleteOnExit();
    // copyFile(tzFile, temp);
    // return findTZVersion(temp);
    // } catch (IOException ex) {
    // ex.printStackTrace();
    // return null;
    // }
    // }

    /**
     * Returns the timezone resource version.
     * 
     * @return The timezone resource version.
     */
    public String getTZVersion() {
        return tzVersion;
    }

    /**
     * Returns the result of getFile().toString().
     * 
     * @return The result of getFile().toString().
     */
    public String toString() {
        return getFile().toString();
    }

    /**
     * Updates the timezone resource in this ICUFile using
     * <code>insertURL</code> as the source of the new timezone resource and
     * the backup directory <code>backupDir</code> to store a copy of the
     * ICUFile.
     * 
     * @param insertURL
     *            The url location of the timezone resource to use.
     * @param backupDir
     *            The directory to store a backup for this ICUFile, or null if
     *            no backup.
     * @throws IOException
     * @throws InterruptedException
     */
    public void update(URL insertURL, File backupDir) throws IOException,
            InterruptedException {
        String message = "Updating " + icuFile.toString() + " ...";
        logger.printlnToBoth("");
        logger.printlnToBoth(message);
        logger.setStatus(message);

        if (!icuFile.canRead() || !icuFile.canWrite())
            throw new IOException("Missing permissions for " + icuFile);
        File backupFile = null;
        if ((backupFile = createBackupFile(icuFile, backupDir)) == null)
            throw new IOException("Failed to create a backup file.");
        if (!copyFile(icuFile, backupFile))
            throw new IOException("Could not replace the original jar.");
        if (!createUpdatedJar(backupFile, icuFile, tzEntry, insertURL))
            throw new IOException("Could not create an updated jar.");

        // get the new timezone resource version
        tzVersion = findEntryTZVersion();

        message = "Successfully updated " + icuFile.toString();
        logger.printlnToBoth(message);
        logger.setStatus(message);
    }

    /**
     * Copies the jar entry <code>insertEntry</code> in <code>inputFile</code>
     * to <code>outputFile</code>.
     * 
     * @param inputFile
     *            The jar file containing <code>insertEntry</code>.
     * @param inputEntry
     *            The entry to copy.
     * @param outputFile
     *            The output file.
     * @return Whether the operation was successful.
     */
    private boolean copyEntry(File inputFile, JarEntry inputEntry,
            File outputFile) {
        logger.loglnToBoth("Copying from " + inputFile + "!/" + inputEntry
                + " to " + outputFile + ".");
        JarFile jar = null;
        InputStream istream = null;
        OutputStream ostream = null;
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesRead;
        boolean success = false;

        try {
            jar = new JarFile(inputFile);
            istream = jar.getInputStream(inputEntry);
            ostream = new FileOutputStream(outputFile);

            while ((bytesRead = istream.read(buffer)) != -1)
                ostream.write(buffer, 0, bytesRead);

            success = true;
            logger.loglnToBoth("Copy successful.");
        } catch (IOException ex) {
            outputFile.delete();
            logger.loglnToBoth("Copy failed.");
        } finally {
            // safely close the streams
            if (jar != null)
                try {
                    jar.close();
                } catch (IOException ex) {
                }
            if (istream != null)
                try {
                    istream.close();
                } catch (IOException ex) {
                }
            if (ostream != null)
                try {
                    ostream.close();
                } catch (IOException ex) {
                }
        }
        return success;
    }

    /**
     * Copies <code>inputFile</code> to <code>outputFile</code>.
     * 
     * @param inputFile
     *            The input file.
     * @param outputFile
     *            The output file.
     * @return Whether the operation was successful.
     */
    private boolean copyFile(File inputFile, File outputFile) {
        logger.loglnToBoth("Copying from " + inputFile + " to " + outputFile
                + ".");
        InputStream istream = null;
        OutputStream ostream = null;
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesRead;
        boolean success = false;

        try {
            istream = new FileInputStream(inputFile);
            ostream = new FileOutputStream(outputFile);

            while ((bytesRead = istream.read(buffer)) != -1)
                ostream.write(buffer, 0, bytesRead);

            success = true;
            logger.loglnToBoth("Copy successful.");
        } catch (IOException ex) {
            outputFile.delete();
            logger.loglnToBoth("Copy failed.");
        } finally {
            // safely close the streams
            if (istream != null)
                try {
                    istream.close();
                } catch (IOException ex) {
                }
            if (ostream != null)
                try {
                    ostream.close();
                } catch (IOException ex) {
                }
        }
        return success;
    }

    /**
     * Creates a temporary file for the jar file <code>inputFile</code> under
     * the directory <code>backupBase</code> and returns it, or returns null
     * if a temporary file could not be created. Does not put any data in the
     * newly created file yet.
     * 
     * @param inputFile
     *            The file to backup.
     * @param backupBase
     *            The directory where backups are to be stored.
     * @return The temporary file that was created.
     */
    private File createBackupFile(File inputFile, File backupBase) {
        logger.loglnToBoth("Creating backup file for + " + inputFile + " at "
                + backupBase + ".");
        String filename = inputFile.getName();
        String suffix = ".jar";
        String prefix = filename.substring(0, filename.length()
                - ".jar".length());

        if (backupBase == null) {
            try {
                File backupFile = File.createTempFile(prefix, suffix);
                backupFile.deleteOnExit();
                return backupFile;
            } catch (IOException ex) {
                return null;
            }
        }

        File backupFile = null;
        File backupDesc = null;
        File backupDir = new File(backupBase.getPath() + File.separator
                + prefix);
        PrintStream ostream = null;

        try {
            backupBase.mkdir();
            backupDir.mkdir();
            backupFile = File.createTempFile(prefix, suffix, backupDir);
            backupDesc = new File(backupDir.getPath() + File.separator + prefix
                    + ".txt");
            backupDesc.createNewFile();
            ostream = new PrintStream(new FileOutputStream(backupDesc));
            ostream.println(inputFile.toString());
            logger.loglnToBoth("Successfully created backup file at "
                    + backupFile + ".");
        } catch (IOException ex) {
            logger.loglnToBoth("Failed to create backup file.");
            if (backupFile != null)
                backupFile.delete();
            if (backupDesc != null)
                backupDesc.delete();
            backupDir.delete();
            backupFile = null;
        } finally {
            if (ostream != null)
                ostream.close();
        }

        return backupFile;
    }

    /**
     * Copies <code>inputFile</code> to <code>outputFile</code>, replacing
     * <code>insertEntry</code> with <code>inputURL</code>.
     * 
     * @param inputFile
     *            The input jar file.
     * @param outputFile
     *            The output jar file.
     * @param insertEntry
     *            The entry to be replaced.
     * @param inputURL
     *            The URL to use in replacing the entry.
     * @return Whether the operation was successful.
     */
    private boolean createUpdatedJar(File inputFile, File outputFile,
            JarEntry insertEntry, URL inputURL) {
        logger.loglnToBoth("Copying " + inputFile + " to " + outputFile
                + ", replacing " + insertEntry + " with " + inputURL + ".");
        JarFile jar = null;
        JarOutputStream ostream = null;
        InputStream istream = null;
        InputStream jstream = null;
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesRead;
        boolean success = false;

        try {
            jar = new JarFile(inputFile);
            ostream = new JarOutputStream(new FileOutputStream(outputFile));
            istream = inputURL.openStream();

            Enumeration e = jar.entries();
            while (e.hasMoreElements()) {
                JarEntry currentEntry = (JarEntry) e.nextElement();

                if (!currentEntry.getName().equals(insertEntry.getName())) {
                    // if the current entry isn't the one that needs updating
                    // write a copy of the old entry from the old file
                    ostream.putNextEntry(new JarEntry(currentEntry.getName()));

                    jstream = jar.getInputStream(currentEntry);
                    while ((bytesRead = jstream.read(buffer)) != -1)
                        ostream.write(buffer, 0, bytesRead);
                    jstream.close();
                } else {
                    // if the current entry *is* the one that needs updating
                    // write a new entry based on the input stream (from the
                    // URL)
                    // currentEntry.setTime(System.currentTimeMillis());
                    ostream.putNextEntry(new JarEntry(currentEntry.getName()));

                    while ((bytesRead = istream.read(buffer)) != -1)
                        ostream.write(buffer, 0, bytesRead);
                }
            }

            success = true;
            logger.loglnToBoth("Copy successful.");
        } catch (IOException ex) {
            outputFile.delete();
            logger.loglnToBoth("Copy failed.");
        } finally {
            // safely close the streams
            if (istream != null)
                try {
                    istream.close();
                } catch (IOException ex) {
                }
            if (ostream != null)
                try {
                    ostream.close();
                } catch (IOException ex) {
                }
            if (jstream != null)
                try {
                    jstream.close();
                } catch (IOException ex) {
                }
            if (jar != null)
                try {
                    jar.close();
                } catch (IOException ex) {
                }
        }
        return success;
    }

    /**
     * Performs the shared work of the constructors. Throws an IOException if
     * <code>file</code>...
     * <ul>
     * <li>does not exist</li>
     * <li>is not a file</li>
     * <li>ends with .ear or .war (these file types are unsupported)</li>
     * <li>does not end with .jar</li>
     * <li>is not updatable according the <code>isUpdatable</code></li>
     * <li>is signed.</li>
     * </ul>
     * If an exception is not thrown, the ICUFile is fully initialized.
     * 
     * @param file
     *            The file to wrap this ICUFile around.
     * @param logger
     *            The current logger.
     * @throws IOException
     */
    private void initialize(File file, Logger log) throws IOException {
        this.icuFile = file;
        this.logger = log;
        String message = null;

        if (!file.exists()) {
            message = "Skipped " + file.getPath() + " (does not exist).";
        } else if (!file.isFile()) {
            message = "Skipped " + file.getPath() + " (not a file).";
        } else if (file.getName().endsWith(".ear")
                || file.getName().endsWith(".war")) {
            message = "Skipped " + file.getPath()
                    + " (this tool does not support .ear and .war files).";
            logger.loglnToBoth(message);
            logger.showInformationDialog(message);
        } else if (!file.getName().endsWith(".jar")) {
            message = "Skipped " + file.getPath() + " (not a jar file).";
        } else if (!isUpdatable()) {
            message = "Skipped " + file.getPath()
                    + " (not an updatable ICU4J jar).";
        } else if (isSigned()) {
            message = "Skipped " + file.getPath()
                    + " (cannot update signed jars).";
            logger.loglnToBoth(message);
            logger.showInformationDialog(message);
        } else if (isEclipseFragment()) {
            message = "Skipped " + file.getPath()
                    + " (eclipse fragments must be updated through ICU).";
            logger.loglnToBoth(message);
            logger.showInformationDialog(message);
        }

        if (message != null)
            throw new IOException(message);

        tzVersion = findEntryTZVersion();
    }

    /**
     * Determines whether the current jar is an Eclipse Data Fragment.
     * 
     * @return Whether the current jar is an Eclipse Fragment.
     */
    private boolean isEclipseDataFragment() {
        return (icuFile.getPath().indexOf(
                "plugins" + File.separator + "com.ibm.icu.data.update") >= 0 && icuFile
                .getName().equals("icu-data.jar"));
    }

    /**
     * Determines whether the current jar is an Eclipse Fragment.
     * 
     * @return Whether the current jar is an Eclipse Fragment.
     */
    private boolean isEclipseFragment() {
        return (isEclipseDataFragment() || isEclipseMainFragment());
    }

    /**
     * Determines whether the current jar is an Eclipse Main Fragment.
     * 
     * @return Whether the current jar is an Eclipse Fragment.
     */
    private boolean isEclipseMainFragment() {
        return (icuFile.getPath().indexOf("plugins") >= 0 && icuFile.getName()
                .startsWith("com.ibm.icu_"));
    }

    /**
     * Determines whether a timezone resource in a jar file is signed.
     * 
     * @return Whether a timezone resource in a jar file is signed.
     */
    private boolean isSigned() {
        return tzEntry.getCertificates() != null;
    }

    /**
     * Gathers information on the jar file represented by this ICUFile object
     * and returns whether it is an updatable ICU4J jar file.
     * 
     * @return Whether the jar file represented by this ICUFile object is an
     *         updatable ICU4J jar file.
     */
    private boolean isUpdatable() {
        JarFile jar = null;
        boolean success = false;

        try {
            // open icuFile as a jar file
            jar = new JarFile(icuFile);

            // get its manifest to determine the ICU version
            Manifest manifest = jar.getManifest();
            icuVersion = ICU_VERSION_UNKNOWN;
            if (manifest != null) {
                Iterator iter = manifest.getEntries().values().iterator();
                while (iter.hasNext()) {
                    Attributes attr = (Attributes) iter.next();
                    String ver = attr
                            .getValue(Attributes.Name.IMPLEMENTATION_VERSION);
                    if (ver != null) {
                        icuVersion = ver;
                        break;
                    }
                }
            }

            // if the jar's directory structure contains TZ_ENTRY_DIR and there
            // is a timezone resource in the jar, then the jar is updatable
            success = (jar.getJarEntry(TZ_ENTRY_DIR) != null)
                    && ((this.tzEntry = getTZEntry(jar)) != null);
        } catch (IOException ex) {
            // unable to create the JarFile or unable to get the Manifest
            // log the unexplained i/o error, but we must drudge on
            logger.loglnToBoth("Error reading " + icuFile.getPath() + ".");
        } finally {
            // close the jar gracefully
            if (jar != null)
                try {
                    jar.close();
                } catch (IOException ex) {
                }
        }

        // return whether the jar is updatable or not
        return success;
    }
}
