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

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.xml.sax.SAXException;

import org.apache.commons.io.IOUtils;

import org.apache.xmlgraphics.io.TempResourceURIGenerator;

import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fonts.FontInfo;

/**
 * A simple cached render pages model.
 * If the page is prepared for later rendering then this saves
 * the page contents to a file and once the page is resolved
 * the contents are reloaded.
 */
public class CachedRenderPagesModel extends RenderPagesModel {

    private Map<PageViewport, URI> pageMap = new HashMap<PageViewport, URI>();

    /** Base directory to save temporary file in, typically points to the user's temp dir. */
    private final URI tempBaseURI;
    private static final TempResourceURIGenerator TEMP_URI_GENERATOR
            = new TempResourceURIGenerator("cached-pages");

    /**
     * Main Constructor
     * @param userAgent FOUserAgent object for process
     * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
     * @param fontInfo FontInfo object
     * @param stream OutputStream
     * @throws FOPException if the renderer cannot be properly initialized
     */
    public CachedRenderPagesModel(FOUserAgent userAgent, String outputFormat,
            FontInfo fontInfo, OutputStream stream) throws FOPException {
        super(userAgent, outputFormat, fontInfo, stream);
        tempBaseURI = TEMP_URI_GENERATOR.generate();
    }

    /** {@inheritDoc} */
    @Override
    protected boolean checkPreparedPages(PageViewport newpage, boolean renderUnresolved) {
        for (Iterator iter = prepared.iterator(); iter.hasNext();) {
            PageViewport pageViewport = (PageViewport)iter.next();
            if (pageViewport.isResolved() || renderUnresolved) {
                if (pageViewport != newpage) {
                    try {
                        // load page from cache
                        URI tempURI = pageMap.get(pageViewport);
                        log.debug("Loading page from: " + tempURI);
                        InputStream inStream = renderer.getUserAgent().getResourceResolver().getResource(tempURI);
                        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(inStream));
                        try {
                            pageViewport.loadPage(in);
                        } finally {
                            IOUtils.closeQuietly(inStream);
                            IOUtils.closeQuietly(in);
                        }
                        pageMap.remove(pageViewport);
                    } catch (Exception e) {
                        AreaEventProducer eventProducer = AreaEventProducer.Provider.get(
                                renderer.getUserAgent().getEventBroadcaster());
                        eventProducer.pageLoadError(this, pageViewport.getPageNumberString(), e);
                    }
                }

                renderPage(pageViewport);
                pageViewport.clear();
                iter.remove();
            } else {
                if (!renderer.supportsOutOfOrder()) {
                    break;
                }
            }
        }
        if (newpage != null && newpage.getPage() != null) {
            savePage(newpage);
            newpage.clear();
        }
        return renderer.supportsOutOfOrder() || prepared.isEmpty();
    }

    /**
     * Save a page.
     * It saves the contents of the page to a file.
     *
     * @param page the page to prepare
     */
    protected void savePage(PageViewport page) {
        try {
            // save page to cache
            ObjectOutputStream tempstream;
            String fname = "/fop-page-" + page.getPageIndex() + ".ser";
            URI tempURI = URI.create(tempBaseURI + fname);
            OutputStream outStream = renderer.getUserAgent().getResourceResolver().getOutputStream(tempURI);
            tempstream = new ObjectOutputStream(new BufferedOutputStream(outStream));
            try {
                page.savePage(tempstream);
            } finally {
                IOUtils.closeQuietly(tempstream);
            }
            pageMap.put(page, tempURI);
            if (log.isDebugEnabled()) {
                log.debug("Page saved to temporary file: " + tempURI);
            }
        } catch (IOException ioe) {
            AreaEventProducer eventProducer
                = AreaEventProducer.Provider.get(
                    renderer.getUserAgent().getEventBroadcaster());
            eventProducer.pageSaveError(this, page.getPageNumberString(), ioe);
        }
    }

    /** {@inheritDoc} */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }
}

