/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed 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.
 */

package android.webkit;

import android.net.http.EventHandler;
import android.net.http.Headers;
import android.os.Handler;
import android.os.Message;

import java.io.IOException;
import java.io.InputStream;


/**
 * This abstract class is used for all content loaders that rely on streaming
 * content into the rendering engine loading framework.
 *
 * The class implements a state machine to load the content into the frame in
 * a similar manor to the way content arrives from the network. The class uses
 * messages to move from one state to the next, which enables async. loading of
 * the streamed content.
 *
 * Classes that inherit from this class must implement two methods, the first
 * method is used to setup the InputStream and notify the loading framework if
 * it can load it's content. The other method allows the derived class to add
 * additional HTTP headers to the response.
 *
 * By default, content loaded with a StreamLoader is marked with a HTTP header
 * that indicates the content should not be cached.
 *
 */
abstract class StreamLoader extends Handler {

    public static final String NO_STORE       = "no-store";

    private static final int MSG_STATUS = 100;  // Send status to loader
    private static final int MSG_HEADERS = 101; // Send headers to loader
    private static final int MSG_DATA = 102;  // Send data to loader
    private static final int MSG_END = 103;  // Send endData to loader

    protected LoadListener mHandler; // loader class
    protected InputStream mDataStream; // stream to read data from
    protected long mContentLength; // content length of data
    private byte [] mData; // buffer to pass data to loader with.

    /**
     * Constructor. Although this class calls the LoadListener, it only calls
     * the EventHandler Interface methods. LoadListener concrete class is used
     * to avoid the penality of calling an interface.
     *
     * @param loadlistener The LoadListener to call with the data.
     */
    StreamLoader(LoadListener loadlistener) {
        mHandler = loadlistener;
    }

    /**
     * This method is called when the derived class should setup mDataStream,
     * and call mHandler.status() to indicate that the load can occur. If it
     * fails to setup, it should still call status() with the error code.
     *
     * @return true if stream was successfully setup
     */
    protected abstract boolean setupStreamAndSendStatus();

    /**
     * This method is called when the headers are about to be sent to the
     * load framework. The derived class has the opportunity to add addition
     * headers.
     *
     * @param headers Map of HTTP headers that will be sent to the loader.
     */
    abstract protected void buildHeaders(Headers headers);


    /**
     * Calling this method starts the load of the content for this StreamLoader.
     * This method simply posts a message to send the status and returns
     * immediately.
     */
    public void load() {
        if (!mHandler.isSynchronous()) {
            sendMessage(obtainMessage(MSG_STATUS));
        } else {
            // Load the stream synchronously.
            if (setupStreamAndSendStatus()) {
                // We were able to open the stream, create the array
                // to pass data to the loader
                mData = new byte[8192];
                sendHeaders();
                while (!sendData());
                closeStreamAndSendEndData();
                mHandler.loadSynchronousMessages();
            }
        }
    }

    /* (non-Javadoc)
     * @see android.os.Handler#handleMessage(android.os.Message)
     */
    public void handleMessage(Message msg) {
        if (WebView.DEBUG && mHandler.isSynchronous()) {
            throw new AssertionError();
        }
        switch(msg.what) {
            case MSG_STATUS:
                if (setupStreamAndSendStatus()) {
                    // We were able to open the stream, create the array
                    // to pass data to the loader
                    mData = new byte[8192];
                    sendMessage(obtainMessage(MSG_HEADERS));
                }
                break;
            case MSG_HEADERS:
                sendHeaders();
                sendMessage(obtainMessage(MSG_DATA));
                break;
            case MSG_DATA:
                if (sendData()) {
                    sendMessage(obtainMessage(MSG_END));
                } else {
                    sendMessage(obtainMessage(MSG_DATA));
                }
                break;
            case MSG_END:
                closeStreamAndSendEndData();
                break;
            default:
                super.handleMessage(msg);
                break;
        }
    }

    /**
     * Construct the headers and pass them to the EventHandler.
     */
    private void sendHeaders() {
        Headers headers = new Headers();
        if (mContentLength > 0) {
            headers.setContentLength(mContentLength);
        }
        headers.setCacheControl(NO_STORE);
        buildHeaders(headers);
        mHandler.headers(headers);
    }

    /**
     * Read data from the stream and pass it to the EventHandler.
     * If an error occurs reading the stream, then an error is sent to the
     * EventHandler, and moves onto the next state - end of data.
     * @return True if all the data has been read. False if sendData should be
     *         called again.
     */
    private boolean sendData() {
        if (mDataStream != null) {
            try {
                int amount = mDataStream.read(mData);
                if (amount > 0) {
                    mHandler.data(mData, amount);
                    return false;
                }
            } catch (IOException ex) {
                mHandler.error(EventHandler.FILE_ERROR,
                               ex.getMessage());
            }
        }
        return true;
    }

    /**
     * Close the stream and inform the EventHandler that load is complete.
     */
    private void closeStreamAndSendEndData() {
        if (mDataStream != null) {
            try {
                mDataStream.close();
            } catch (IOException ex) {
                // ignore.
            }
        }
        mHandler.endData();
    }

}
