/*
 * 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.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
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.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
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.apps.io.InternalResourceResolver;
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 = 9129238336422194339L;

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

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

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

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

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
        ois.defaultReadObject();
    }

    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)
     * @deprecated use {@link #loadFrom(File)} instead
     */
    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 BufferedInputStream(new FileInputStream(cacheFile));
                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
     * @deprecated use {@link #saveTo(File)} instead
     */
    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 {
                    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) {
            URI embedFile = fontInfo.getEmbedURI();
            URI metricsFile = fontInfo.getMetricsURI();
            return (embedFile != null) ? embedFile.toASCIIString() : metricsFile.toASCIIString();
        }
        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 (String urlStr : urls) {
            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 HashMap<String, CachedFontFile>();
        }
        return fontfileMap;
    }

    /**
     * Adds a font info to cache
     *
     * @param fontInfo
     *            font info
     */
    public void addFont(EmbedFontInfo fontInfo, InternalResourceResolver resourceResolver) {
        String cacheKey = getCacheKey(fontInfo);
        synchronized (changeLock) {
            CachedFontFile cachedFontFile;
            if (containsFont(cacheKey)) {
                cachedFontFile = getFontFileMap().get(cacheKey);
                if (!cachedFontFile.containsFont(fontInfo)) {
                    cachedFontFile.put(fontInfo);
                }
            } else {
                // try and determine modified date
                URI fontUri = resourceResolver.resolveFromBase(fontInfo.getEmbedURI());
                long lastModified = getLastModified(fontUri);
                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) ? 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 = getFailedFontMap().get(
                        embedUrl);
                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, lastModified);
                changed = true;
            }
        }
    }

    private Map<String, Long> getFailedFontMap() {
        if (failedFontMap == null) {
            failedFontMap = new 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 URI.
     *
     * @param uri the URI
     * @return the last modified date/time
     */
    public static long getLastModified(URI uri) {
        try {
            URL url = uri.toURL();
            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;

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

        private Map<String, EmbedFontInfo> getFileFontsMap() {
            if (filefontsMap == null) {
                filefontsMap = new 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 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;
        }

    }
}
