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

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;

import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.util.Map;

/**
 * Encapsulates a resource response. Applications can return an instance of this
 * class from {@link WebViewClient#shouldInterceptRequest} to provide a custom
 * response when the WebView requests a particular resource.
 */
public class WebResourceResponse {
    @UnsupportedAppUsage
    private boolean mImmutable;
    private String mMimeType;
    private String mEncoding;
    @UnsupportedAppUsage
    private int mStatusCode;
    private String mReasonPhrase;
    private Map<String, String> mResponseHeaders;
    private InputStream mInputStream;

    /**
     * Constructs a resource response with the given MIME type, character encoding,
     * and input stream. Callers must implement
     * {@link InputStream#read(byte[]) InputStream.read(byte[])} for the input
     * stream.
     *
     * <p class="note"><b>Note:</b> The MIME type and character encoding must
     * be specified as separate parameters (for example {@code "text/html"} and
     * {@code "utf-8"}), not a single value like the {@code "text/html; charset=utf-8"}
     * format used in the HTTP Content-Type header. Do not use the value of a HTTP
     * Content-Encoding header for {@code encoding}, as that header does not specify a
     * character encoding. Content without a defined character encoding (for example
     * image resources) should pass {@code null} for {@code encoding}.
     *
     * @param mimeType the resource response's MIME type, for example {@code "text/html"}.
     * @param encoding the resource response's character encoding, for example {@code "utf-8"}.
     * @param data the input stream that provides the resource response's data. Must not be a
     *             StringBufferInputStream.
     */
    public WebResourceResponse(String mimeType, String encoding,
            InputStream data) {
        mMimeType = mimeType;
        mEncoding = encoding;
        setData(data);
    }

    /**
     * Constructs a resource response with the given parameters. Callers must
     * implement {@link InputStream#read(byte[]) InputStream.read(byte[])} for
     * the input stream.
     *
     * <p class="note"><b>Note:</b> See {@link #WebResourceResponse(String,String,InputStream)}
     * for details on what should be specified for {@code mimeType} and {@code encoding}.
     *
     * @param mimeType the resource response's MIME type, for example {@code "text/html"}.
     * @param encoding the resource response's character encoding, for example {@code "utf-8"}.
     * @param statusCode the status code needs to be in the ranges [100, 299], [400, 599].
     *                   Causing a redirect by specifying a 3xx code is not supported.
     * @param reasonPhrase the phrase describing the status code, for example "OK". Must be
     *                     non-empty.
     * @param responseHeaders the resource response's headers represented as a mapping of header
     *                        name -> header value.
     * @param data the input stream that provides the resource response's data. Must not be a
     *             StringBufferInputStream.
     */
    public WebResourceResponse(String mimeType, String encoding, int statusCode,
            @NonNull String reasonPhrase, Map<String, String> responseHeaders, InputStream data) {
        this(mimeType, encoding, data);
        setStatusCodeAndReasonPhrase(statusCode, reasonPhrase);
        setResponseHeaders(responseHeaders);
    }

    /**
     * Sets the resource response's MIME type, for example &quot;text/html&quot;.
     *
     * @param mimeType The resource response's MIME type
     */
    public void setMimeType(String mimeType) {
        checkImmutable();
        mMimeType = mimeType;
    }

    /**
     * Gets the resource response's MIME type.
     *
     * @return The resource response's MIME type
     */
    public String getMimeType() {
        return mMimeType;
    }

    /**
     * Sets the resource response's encoding, for example &quot;UTF-8&quot;. This is used
     * to decode the data from the input stream.
     *
     * @param encoding The resource response's encoding
     */
    public void setEncoding(String encoding) {
        checkImmutable();
        mEncoding = encoding;
    }

    /**
     * Gets the resource response's encoding.
     *
     * @return The resource response's encoding
     */
    public String getEncoding() {
        return mEncoding;
    }

    /**
     * Sets the resource response's status code and reason phrase.
     *
     * @param statusCode the status code needs to be in the ranges [100, 299], [400, 599].
     *                   Causing a redirect by specifying a 3xx code is not supported.
     * @param reasonPhrase the phrase describing the status code, for example "OK". Must be
     *                     non-empty.
     */
    public void setStatusCodeAndReasonPhrase(int statusCode, @NonNull String reasonPhrase) {
        checkImmutable();
        if (statusCode < 100)
            throw new IllegalArgumentException("statusCode can't be less than 100.");
        if (statusCode > 599)
            throw new IllegalArgumentException("statusCode can't be greater than 599.");
        if (statusCode > 299 && statusCode < 400)
            throw new IllegalArgumentException("statusCode can't be in the [300, 399] range.");
        if (reasonPhrase == null)
            throw new IllegalArgumentException("reasonPhrase can't be null.");
        if (reasonPhrase.trim().isEmpty())
            throw new IllegalArgumentException("reasonPhrase can't be empty.");
        for (int i = 0; i < reasonPhrase.length(); i++) {
            int c = reasonPhrase.charAt(i);
            if (c > 0x7F) {
                throw new IllegalArgumentException(
                        "reasonPhrase can't contain non-ASCII characters.");
            }
        }
        mStatusCode = statusCode;
        mReasonPhrase = reasonPhrase;
    }

    /**
     * Gets the resource response's status code.
     *
     * @return The resource response's status code.
     */
    public int getStatusCode() {
        return mStatusCode;
    }

    /**
     * Gets the description of the resource response's status code.
     *
     * @return The description of the resource response's status code.
     */
    public String getReasonPhrase() {
        return mReasonPhrase;
    }

    /**
     * Sets the headers for the resource response.
     *
     * @param headers Mapping of header name -> header value.
     */
    public void setResponseHeaders(Map<String, String> headers) {
        checkImmutable();
        mResponseHeaders = headers;
    }

    /**
     * Gets the headers for the resource response.
     *
     * @return The headers for the resource response.
     */
    public Map<String, String> getResponseHeaders() {
        return mResponseHeaders;
    }

    /**
     * Sets the input stream that provides the resource response's data. Callers
     * must implement {@link InputStream#read(byte[]) InputStream.read(byte[])}.
     *
     * @param data the input stream that provides the resource response's data. Must not be a
     *             StringBufferInputStream.
     */
    public void setData(InputStream data) {
        checkImmutable();
        // If data is (or is a subclass of) StringBufferInputStream
        if (data != null && StringBufferInputStream.class.isAssignableFrom(data.getClass())) {
            throw new IllegalArgumentException("StringBufferInputStream is deprecated and must " +
                "not be passed to a WebResourceResponse");
        }
        mInputStream = data;
    }

    /**
     * Gets the input stream that provides the resource response's data.
     *
     * @return The input stream that provides the resource response's data
     */
    public InputStream getData() {
        return mInputStream;
    }

    /**
     * The internal version of the constructor that doesn't perform arguments checks.
     * @hide
     */
    @SystemApi
    public WebResourceResponse(boolean immutable, String mimeType, String encoding, int statusCode,
            String reasonPhrase, Map<String, String> responseHeaders, InputStream data) {
        mImmutable = immutable;
        mMimeType = mimeType;
        mEncoding = encoding;
        mStatusCode = statusCode;
        mReasonPhrase = reasonPhrase;
        mResponseHeaders = responseHeaders;
        mInputStream = data;
    }

    private void checkImmutable() {
        if (mImmutable)
            throw new IllegalStateException("This WebResourceResponse instance is immutable");
    }
}
