/*
 * Copyright (C) 2010 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 libcore.net.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.CacheRequest;
import libcore.io.Streams;

/**
 * An input stream for the body of an HTTP response.
 *
 * <p>Since a single socket's input stream may be used to read multiple HTTP
 * responses from the same server, subclasses shouldn't close the socket stream.
 *
 * <p>A side effect of reading an HTTP response is that the response cache
 * is populated. If the stream is closed early, that cache entry will be
 * invalidated.
 */
abstract class AbstractHttpInputStream extends InputStream {
    protected final InputStream in;
    protected final HttpEngine httpEngine;
    private final CacheRequest cacheRequest;
    private final OutputStream cacheBody;
    protected boolean closed;

    AbstractHttpInputStream(InputStream in, HttpEngine httpEngine,
            CacheRequest cacheRequest) throws IOException {
        this.in = in;
        this.httpEngine = httpEngine;

        OutputStream cacheBody = cacheRequest != null ? cacheRequest.getBody() : null;

        // some apps return a null body; for compatibility we treat that like a null cache request
        if (cacheBody == null) {
            cacheRequest = null;
        }

        this.cacheBody = cacheBody;
        this.cacheRequest = cacheRequest;
    }

    /**
     * read() is implemented using read(byte[], int, int) so subclasses only
     * need to override the latter.
     */
    @Override public final int read() throws IOException {
        return Streams.readSingleByte(this);
    }

    protected final void checkNotClosed() throws IOException {
        if (closed) {
            throw new IOException("stream closed");
        }
    }

    protected final void cacheWrite(byte[] buffer, int offset, int count) throws IOException {
        if (cacheBody != null) {
            cacheBody.write(buffer, offset, count);
        }
    }

    /**
     * Closes the cache entry and makes the socket available for reuse. This
     * should be invoked when the end of the body has been reached.
     */
    protected final void endOfInput(boolean reuseSocket) throws IOException {
        if (cacheRequest != null) {
            cacheBody.close();
        }
        httpEngine.release(reuseSocket);
    }

    /**
     * Calls abort on the cache entry and disconnects the socket. This
     * should be invoked when the connection is closed unexpectedly to
     * invalidate the cache entry and to prevent the HTTP connection from
     * being reused. HTTP messages are sent in serial so whenever a message
     * cannot be read to completion, subsequent messages cannot be read
     * either and the connection must be discarded.
     *
     * <p>An earlier implementation skipped the remaining bytes, but this
     * requires that the entire transfer be completed. If the intention was
     * to cancel the transfer, closing the connection is the only solution.
     */
    protected final void unexpectedEndOfInput() {
        if (cacheRequest != null) {
            cacheRequest.abort();
        }
        httpEngine.release(false);
    }
}
