/*
 * 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.
 */

/* $Id$ */

package org.apache.fop.fonts;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.apps.FOPException;
import org.apache.fop.util.LogUtil;

/**
 * Fop cache (currently only used for font info caching)
 */
public final class FontCache implements Serializable {

    /**
     * Serialization Version UID. Change this value if you want to make sure the user's cache
     * file is purged after an update.
     */
    private static final long serialVersionUID = 605232520271754719L;

    /** logging instance */
    private static Log log = LogFactory.getLog(FontCache.class);

    /** FOP's user directory name */
    private static final String FOP_USER_DIR = ".fop";

    /** font cache file path */
    private static final String DEFAULT_CACHE_FILENAME = "fop-fonts.cache";


    /** has this cache been changed since it was last read? */
    private transient boolean changed = false;

    /** change lock */
    private final boolean[] changeLock = new boolean[1];

    /** master mapping of font url -> font info.  This needs to be
     *  a list, since a TTC file may contain more than 1 font. */
    private Map/*<String, CachedFontFile>*/ fontfileMap = null;

    /** mapping of font url -> file modified date (for all fonts that have failed to load) */
    private Map failedFontMap/*<String, Long>*/ = null;

    /**
     * Default constructor
     */
    public FontCache() {
        //nop
    }

    private static File getUserHome() {
        return toDirectory(System.getProperty("user.home"));
    }

    private static File getTempDirectory() {
        return toDirectory(System.getProperty("java.io.tmpdir"));
    }

    private static File toDirectory(String path) {
        if (path != null) {
            File dir = new File(path);
            if (dir.exists()) {
                return dir;
            }
        }
        return null;
    }

    /**
     * Returns the default font cache file.
     * @param forWriting true if the user directory should be created
     * @return the default font cache file
     */
    public static File getDefaultCacheFile(boolean forWriting) {
        File userHome = getUserHome();
        if (userHome != null) {
            File fopUserDir = new File(userHome, FOP_USER_DIR);
            if (forWriting) {
                boolean writable = fopUserDir.canWrite();
                if (!fopUserDir.exists()) {
                    writable = fopUserDir.mkdir();
                }
                if (!writable) {
                    userHome = getTempDirectory();
                    fopUserDir = new File(userHome, FOP_USER_DIR);
                    fopUserDir.mkdir();
                }
            }
            return new File(fopUserDir, DEFAULT_CACHE_FILENAME);
        }
        return new File(FOP_USER_DIR);
    }

    /**
     * Reads the default font cache file and returns its contents.
     * @return the font cache deserialized from the file (or null if no cache file exists or if
     *         it could not be read)
     */
    public static FontCache load() {
        return loadFrom(getDefaultCacheFile(false));
    }

    /**
     * Reads a font cache file and returns its contents.
     * @param cacheFile the cache file
     * @return the font cache deserialized from the file (or null if no cache file exists or if
     *         it could not be read)
     */
    public static FontCache loadFrom(File cacheFile) {
        if (cacheFile.exists()) {
            try {
                if (log.isTraceEnabled()) {
                    log.trace("Loading font cache from " + cacheFile.getCanonicalPath());
                }
                InputStream in = new java.io.FileInputStream(cacheFile);
                in = new java.io.BufferedInputStream(in);
                ObjectInputStream oin = new ObjectInputStream(in);
                try {
                    return (FontCache)oin.readObject();
                } finally {
                    IOUtils.closeQuietly(oin);
                }
            } catch (ClassNotFoundException e) {
                //We don't really care about the exception since it's just a cache file
                log.warn("Could not read font cache. Discarding font cache file. Reason: "
                        + e.getMessage());
            } catch (IOException ioe) {
                //We don't really care about the exception since it's just a cache file
                log.warn("I/O exception while reading font cache (" + ioe.getMessage()
                        + "). Discarding font cache file.");
                try {
                    cacheFile.delete();
                } catch (SecurityException ex) {
                    log.warn("Failed to delete font cache file: " + cacheFile.getAbsolutePath());
                }
            }
        }
        return null;
    }

    /**
     * Writes the font cache to disk.
     * @throws FOPException fop exception
     */
    public void save() throws FOPException {
        saveTo(getDefaultCacheFile(true));
    }

    /**
     * Writes the font cache to disk.
     * @param cacheFile the file to write to
     * @throws FOPException fop exception
     */
    public void saveTo(File cacheFile) throws FOPException {
        synchronized (changeLock) {
            if (changed) {
                try {
                    if (log.isTraceEnabled()) {
                        log.trace("Writing font cache to " + cacheFile.getCanonicalPath());
                    }
                    OutputStream out = new java.io.FileOutputStream(cacheFile);
                    out = new java.io.BufferedOutputStream(out);
                    ObjectOutputStream oout = new ObjectOutputStream(out);
                    try {
                        oout.writeObject(this);
                    } finally {
                        IOUtils.closeQuietly(oout);
                    }
                } catch (IOException ioe) {
                    LogUtil.handleException(log, ioe, true);
                }
                changed = false;
                log.trace("Cache file written.");
            }
        }
    }

    /**
     * creates a key given a font info for the font mapping
     * @param fontInfo font info
     * @return font cache key
     */
    protected static String getCacheKey(EmbedFontInfo fontInfo) {
        if (fontInfo != null) {
            String embedFile = fontInfo.getEmbedFile();
            String metricsFile = fontInfo.getMetricsFile();
            return (embedFile != null) ? embedFile : metricsFile;
        }
        return null;
    }

    /**
     * cache has been updated since it was read
     * @return if this cache has changed
     */
    public boolean hasChanged() {
        return this.changed;
    }

    /**
     * is this font in the cache?
     * @param embedUrl font info
     * @return boolean
     */
    public boolean containsFont(String embedUrl) {
        return (embedUrl != null
                && getFontFileMap().containsKey(embedUrl));
    }

    /**
     * is this font info in the cache?
     * @param fontInfo font info
     * @return font
     */
    public boolean containsFont(EmbedFontInfo fontInfo) {
        return (fontInfo != null
                && getFontFileMap().containsKey(getCacheKey(fontInfo)));
    }

    /**
     * Tries to identify a File instance from an array of URLs. If there's no file URL in the
     * array, the method returns null.
     * @param urls array of possible font urls
     * @return file font file
     */
    public static File getFileFromUrls(String[] urls) {
        for (int i = 0; i < urls.length; i++) {
            String urlStr = urls[i];
            if (urlStr != null) {
                File fontFile = null;
                if (urlStr.startsWith("file:")) {
                    try {
                        URL url = new URL(urlStr);
                        fontFile = FileUtils.toFile(url);
                    } catch (MalformedURLException mfue) {
                        // do nothing
                    }
                }
                if (fontFile == null) {
                    fontFile = new File(urlStr);
                }
                if (fontFile.exists() && fontFile.canRead()) {
                    return fontFile;
                }
            }
        }
        return null;
    }

    private Map/*<String, CachedFontFile>*/ getFontFileMap() {
        if (fontfileMap == null) {
            fontfileMap = new java.util.HashMap/*<String, CachedFontFile>*/();
        }
        return fontfileMap;
    }

    /**
     * Adds a font info to cache
     * @param fontInfo font info
     */
    public void addFont(EmbedFontInfo fontInfo) {
        String cacheKey = getCacheKey(fontInfo);
        synchronized (changeLock) {
            CachedFontFile cachedFontFile;
            if (containsFont(cacheKey)) {
                cachedFontFile = (CachedFontFile)getFontFileMap().get(cacheKey);
                if (!cachedFontFile.containsFont(fontInfo)) {
                    cachedFontFile.put(fontInfo);
                }
            } else {
                // try and determine modified date
                File fontFile = getFileFromUrls(new String[]
                                     {fontInfo.getEmbedFile(), fontInfo.getMetricsFile()});
                long lastModified = (fontFile != null ? fontFile.lastModified() : -1);
                cachedFontFile = new CachedFontFile(lastModified);
                if (log.isTraceEnabled()) {
                    log.trace("Font added to cache: " + cacheKey);
                }
                cachedFontFile.put(fontInfo);
                getFontFileMap().put(cacheKey, cachedFontFile);
                changed = true;
            }
        }
    }

    /**
     * Returns a font from the cache.
     * @param embedUrl font info
     * @return CachedFontFile object
     */
    public CachedFontFile getFontFile(String embedUrl) {
        return containsFont(embedUrl) ? (CachedFontFile) getFontFileMap().get(embedUrl) : null;
    }

    /**
     * Returns the EmbedFontInfo instances belonging to a font file. If the font file was
     * modified since it was cached the entry is removed and null is returned.
     * @param embedUrl the font URL
     * @param lastModified the last modified date/time of the font file
     * @return the EmbedFontInfo instances or null if there's no cached entry or if it is outdated
     */
    public EmbedFontInfo[] getFontInfos(String embedUrl, long lastModified) {
        CachedFontFile cff = getFontFile(embedUrl);
        if (cff.lastModified() == lastModified) {
            return cff.getEmbedFontInfos();
        } else {
            removeFont(embedUrl);
            return null;
        }
    }

    /**
     * removes font from cache
     * @param embedUrl embed url
     */
    public void removeFont(String embedUrl) {
        synchronized (changeLock) {
            if (containsFont(embedUrl)) {
                if (log.isTraceEnabled()) {
                    log.trace("Font removed from cache: " + embedUrl);
                }
                getFontFileMap().remove(embedUrl);
                changed = true;
            }
        }
    }

    /**
     * has this font previously failed to load?
     * @param embedUrl embed url
     * @param lastModified last modified
     * @return whether this is a failed font
     */
    public boolean isFailedFont(String embedUrl, long lastModified) {
        synchronized (changeLock) {
            if (getFailedFontMap().containsKey(embedUrl)) {
                long failedLastModified = ((Long)getFailedFontMap().get(embedUrl)).longValue();
                if (lastModified != failedLastModified) {
                    // this font has been changed so lets remove it
                    // from failed font map for now
                    getFailedFontMap().remove(embedUrl);
                    changed = true;
                }
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * Registers a failed font with the cache
     * @param embedUrl embed url
     * @param lastModified time last modified
     */
    public void registerFailedFont(String embedUrl, long lastModified) {
        synchronized (changeLock) {
            if (!getFailedFontMap().containsKey(embedUrl)) {
                getFailedFontMap().put(embedUrl, new Long(lastModified));
                changed = true;
            }
        }
    }

    private Map/*<String, Long>*/ getFailedFontMap() {
        if (failedFontMap == null) {
            failedFontMap = new java.util.HashMap/*<String, Long>*/();
        }
        return failedFontMap;
    }

    /**
     * Clears font cache
     */
    public void clear() {
        synchronized (changeLock) {
            if (log.isTraceEnabled()) {
                log.trace("Font cache cleared.");
            }
            fontfileMap = null;
            failedFontMap = null;
            changed = true;
        }
    }

    /**
     * Retrieve the last modified date/time of a URL.
     * @param url the URL
     * @return the last modified date/time
     */
    public static long getLastModified(URL url) {
        try {
            URLConnection conn = url.openConnection();
            try {
                return conn.getLastModified();
            } finally {
                //An InputStream is created even if it's not accessed, but we need to close it.
                IOUtils.closeQuietly(conn.getInputStream());
            }
        } catch (IOException e) {
            // Should never happen, because URL must be local
            log.debug("IOError: " + e.getMessage());
            return 0;
        }
    }

    private static class CachedFontFile implements Serializable {
        private static final long serialVersionUID = 4524237324330578883L;

        /** file modify date (if available) */
        private long lastModified = -1;

        private Map/*<String, EmbedFontInfo>*/ filefontsMap = null;

        public CachedFontFile(long lastModified) {
            setLastModified(lastModified);
        }

        private Map/*<String, EmbedFontInfo>*/ getFileFontsMap() {
            if (filefontsMap == null) {
                filefontsMap = new java.util.HashMap/*<String, EmbedFontInfo>*/();
            }
            return filefontsMap;
        }

        void put(EmbedFontInfo efi) {
            getFileFontsMap().put(efi.getPostScriptName(), efi);
        }

        public boolean containsFont(EmbedFontInfo efi) {
            return efi.getPostScriptName() != null
                    && getFileFontsMap().containsKey(efi.getPostScriptName());
        }

        public EmbedFontInfo[] getEmbedFontInfos() {
            return (EmbedFontInfo[])getFileFontsMap().values().toArray(
                    new EmbedFontInfo[getFileFontsMap().size()]);
        }

        /**
         * Gets the modified timestamp for font file (not always available)
         * @return modified timestamp
         */
        public long lastModified() {
            return this.lastModified;
        }

        /**
         * Gets the modified timestamp for font file
         * (used for the purposes of font info caching)
         * @param lastModified modified font file timestamp
         */
        public void setLastModified(long lastModified) {
            this.lastModified = lastModified;
        }

        /**
         * @return string representation of this object
         * {@inheritDoc}
         */
        public String toString() {
            return super.toString() + ", lastModified=" + lastModified;
        }

    }
}
