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

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.modca.ResourceGroup;
import org.apache.fop.afp.modca.StreamedResourceGroup;

/**
 * Manages the streaming of the AFP output
 */
public class AFPStreamer implements Streamable {
    /** Static logging instance */
    private static final Log log = LogFactory.getLog(AFPStreamer.class);

    private static final String AFPDATASTREAM_TEMP_FILE_PREFIX = "AFPDataStream_";

    private static final int BUFFER_SIZE = 4096; // 4k writing buffer

    private static final String DEFAULT_EXTERNAL_RESOURCE_FILENAME = "resources.afp";


    private final Factory factory;

    /** A mapping of external resource destinations to resource groups */
    private final Map/*<String,AFPExternalResourceGroup>*/pathResourceGroupMap
        = new java.util.HashMap/*<String,AFPExternalResourceGroup>*/();

    private StreamedResourceGroup printFileResourceGroup;

    /** Sets the default resource group file path */
    private String defaultResourceGroupFilePath = DEFAULT_EXTERNAL_RESOURCE_FILENAME;

    private File tempFile;

    /** temporary document outputstream */
    private OutputStream documentOutputStream;

    /** the final outputstream */
    private OutputStream outputStream;

    private RandomAccessFile documentFile;

    private DataStream dataStream;

    /**
     * Main constructor
     *
     * @param factory a factory
     */
    public AFPStreamer(Factory factory) {
        this.factory = factory;
    }

    /**
     * Creates a new DataStream
     *
     * @param paintingState the AFP painting state
     * @return a new {@link DataStream}
     * @throws IOException thrown if an I/O exception of some sort has occurred
     */
    public DataStream createDataStream(AFPPaintingState paintingState) throws IOException {
        this.tempFile = File.createTempFile(AFPDATASTREAM_TEMP_FILE_PREFIX, null);
        this.documentFile = new RandomAccessFile(tempFile, "rw");
        this.documentOutputStream = new BufferedOutputStream(
                new FileOutputStream(documentFile.getFD()));
        this.dataStream = factory.createDataStream(paintingState, documentOutputStream);
        return dataStream;
    }

    /**
     * Sets the default resource group file path
     *
     * @param filePath the default resource group file path
     */
    public void setDefaultResourceGroupFilePath(String filePath) {
        this.defaultResourceGroupFilePath = filePath;
    }

    /**
     * Returns the resource group for a given resource info
     *
     * @param level a resource level
     * @return a resource group for the given resource info
     */
    public ResourceGroup getResourceGroup(AFPResourceLevel level) {
        ResourceGroup resourceGroup = null;
        if (level.isInline()) { // no resource group for inline level
            return null;
        }
        if (level.isExternal()) {
            String filePath = level.getExternalFilePath();
            if (filePath == null) {
                log.warn("No file path provided for external resource, using default.");
                filePath = defaultResourceGroupFilePath;
            }
            resourceGroup = (ResourceGroup)pathResourceGroupMap.get(filePath);
            if (resourceGroup == null) {
                OutputStream os = null;
                try {
                    os = new BufferedOutputStream(new FileOutputStream(filePath));
                } catch (FileNotFoundException fnfe) {
                    log.error("Failed to create/open external resource group file '"
                            + filePath + "'");
                } finally {
                    if (os != null) {
                        resourceGroup = factory.createStreamedResourceGroup(os);
                        pathResourceGroupMap.put(filePath, resourceGroup);
                    }
                }
            }
        } else if (level.isPrintFile()) {
            if (printFileResourceGroup == null) {
                // use final outputstream for print-file resource group
                printFileResourceGroup = factory.createStreamedResourceGroup(outputStream);
            }
            resourceGroup = printFileResourceGroup;
        } else {
            // resource group in afp document datastream
            resourceGroup = dataStream.getResourceGroup(level);
        }
        return resourceGroup;
    }

    /**
     * Closes off the AFP stream writing the document stream
     *
     * @throws IOException if an an I/O exception of some sort has occurred
     */
        // write out any external resource groups
    public void close() throws IOException {
        Iterator it = pathResourceGroupMap.entrySet().iterator();
        while (it.hasNext()) {
            StreamedResourceGroup resourceGroup = (StreamedResourceGroup)it.next();
            resourceGroup.close();
        }

        // close any open print-file resource group
        if (printFileResourceGroup != null) {
            printFileResourceGroup.close();
        }

        // write out document
        writeToStream(outputStream);

        outputStream.close();

        // delete temporary file
        tempFile.delete();
    }

    /**
     * Sets the final outputstream
     *
     * @param outputStream an outputstream
     */
    public void setOutputStream(OutputStream outputStream) {
        this.outputStream = outputStream;
    }

    /** {@inheritDoc} */
    public void writeToStream(OutputStream os) throws IOException {
//        long start = System.currentTimeMillis();
        int len = (int)documentFile.length();
        int numChunks = len / BUFFER_SIZE;
        int remainingChunkSize = len % BUFFER_SIZE;
        byte[] buffer;

        documentFile.seek(0);
        if (numChunks > 0) {
            buffer = new byte[BUFFER_SIZE];
            for (int i = 0; i < numChunks; i++) {
                documentFile.read(buffer, 0, BUFFER_SIZE);
                os.write(buffer, 0, BUFFER_SIZE);
            }
        } else {
            buffer = new byte[remainingChunkSize];
        }
        if (remainingChunkSize > 0) {
            documentFile.read(buffer, 0, remainingChunkSize);
            os.write(buffer, 0, remainingChunkSize);
        }
        os.flush();
//        long end = System.currentTimeMillis();
//        log.debug("writing time " + (end - start) + "ms");
    }
}