/*
 * 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.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.io.IOUtils;
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;
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.apps.io.TempResourceURIGenerator;

/**
 * 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 DEFAULT_EXTERNAL_RESOURCE_FILENAME = "resources.afp";

    private static final TempResourceURIGenerator TEMP_URI_GENERATOR
            = new TempResourceURIGenerator("AFPDataStream_");

    private final Factory factory;

    private final InternalResourceResolver resourceResolver;

    /** A mapping of external resource destinations to resource groups */
    private final Map<URI, ResourceGroup> pathResourceGroupMap = new HashMap<URI, ResourceGroup>();

    private StreamedResourceGroup printFileResourceGroup;

    /** Sets the default resource group file path */
    private URI defaultResourceGroupUri;

    private final URI tempUri;

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

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

    private DataStream dataStream;

    /**
     * Main constructor
     *
     * @param factory a factory
     * @param resourceResolver resource resolver
     */
    public AFPStreamer(Factory factory, InternalResourceResolver resourceResolver) {
        this.factory = factory;
        this.resourceResolver = resourceResolver;
        this.tempUri = TEMP_URI_GENERATOR.generate();
        defaultResourceGroupUri = URI.create(DEFAULT_EXTERNAL_RESOURCE_FILENAME);

    }

    /**
     * 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.tempOutputStream = new BufferedOutputStream(resourceResolver.getOutputStream(tempUri));
        this.dataStream = factory.createDataStream(paintingState, tempOutputStream);
        return dataStream;
    }

    /**
     * Sets the default resource group URI.
     *
     * @param uri the default resource group URI
     */
    public void setDefaultResourceGroupUri(URI uri) {
        this.defaultResourceGroupUri = uri;
    }

    /**
     * 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()) {
            URI uri = level.getExternalURI();
            if (uri == null) {
                LOG.warn("No file path provided for external resource, using default.");
                uri = defaultResourceGroupUri;
            }
            resourceGroup = pathResourceGroupMap.get(uri);
            if (resourceGroup == null) {
                OutputStream os = null;
                try {
                    os = new BufferedOutputStream(resourceResolver.getOutputStream(uri));
                } catch (IOException ioe) {
                    LOG.error("Failed to create/open external resource group for uri '"
                            + uri + "'");
                } finally {
                    if (os != null) {
                        resourceGroup = factory.createStreamedResourceGroup(os);
                        pathResourceGroupMap.put(uri, 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.values().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();
    }

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

    /** {@inheritDoc} */
    public void writeToStream(OutputStream os) throws IOException {
        tempOutputStream.close();
        InputStream tempInputStream = resourceResolver.getResource(tempUri);
        IOUtils.copy(tempInputStream, os);
        //TODO this should notify the stream provider that it is safe to delete the temp data
        tempInputStream.close();
        os.flush();
    }
}
