/*
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "WebURLResponse.h"

#include "WebKitDLL.h"
#include "WebKit.h"

#include "COMPropertyBag.h"
#include "MarshallingHelpers.h"

#if USE(CG)
#include <CoreGraphics/CoreGraphics.h>
#endif

#if USE(CFURLCONNECTION)
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#endif

#include <WebCore/BString.h>
#include <WebCore/URL.h>
#include <WebCore/LocalizedStrings.h>
#include <WebCore/ResourceHandle.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <wchar.h>

using namespace WebCore;

static String localizedShortDescriptionForStatusCode(int statusCode)
{
    String result;
    if (statusCode < 100 || statusCode >= 600)
        result = WEB_UI_STRING("server error", "HTTP result code string");
    else if (statusCode >= 100 && statusCode <= 199) {
        switch (statusCode) {
            case 100:
                result = WEB_UI_STRING("continue", "HTTP result code string");
                break;
            case 101:
                result = WEB_UI_STRING("switching protocols", "HTTP result code string");
                break;
            default:
                result = WEB_UI_STRING("informational", "HTTP result code string");
                break;
        }
    } else if (statusCode >= 200 && statusCode <= 299) {
        switch (statusCode) {
            case 200:
                result = WEB_UI_STRING("no error", "HTTP result code string");
                break;
            case 201:
                result = WEB_UI_STRING("created", "HTTP result code string");
                break;
            case 202:
                result = WEB_UI_STRING("accepted", "HTTP result code string");
                break;
            case 203:
                result = WEB_UI_STRING("non-authoritative information", "HTTP result code string");
                break;
            case 204:
                result = WEB_UI_STRING("no content", "HTTP result code string");
                break;
            case 205:
                result = WEB_UI_STRING("reset content", "HTTP result code string");
                break;
            case 206:
                result = WEB_UI_STRING("partial content", "HTTP result code string");
                break;
            default:
                result = WEB_UI_STRING("success", "HTTP result code string");
                break;
        } 
    } else if (statusCode >= 300 && statusCode <= 399) {
        switch (statusCode) {
            case 300:
                result = WEB_UI_STRING("multiple choices", "HTTP result code string");
                break;
            case 301:
                result = WEB_UI_STRING("moved permanently", "HTTP result code string");
                break;
            case 302:
                result = WEB_UI_STRING("found", "HTTP result code string");
                break;
            case 303:
                result = WEB_UI_STRING("see other", "HTTP result code string");
                break;
            case 304:
                result = WEB_UI_STRING("not modified", "HTTP result code string");
                break;
            case 305:
                result = WEB_UI_STRING("needs proxy", "HTTP result code string");
                break;
            case 307:
                result = WEB_UI_STRING("temporarily redirected", "HTTP result code string");
                break;
            case 306:   // 306 status code unused in HTTP
            default:
                result = WEB_UI_STRING("redirected", "HTTP result code string");
                break;
        }
    } else if (statusCode >= 400 && statusCode <= 499) {
        switch (statusCode) {
            case 400:
                result = WEB_UI_STRING("bad request", "HTTP result code string");
                break;
            case 401:
                result = WEB_UI_STRING("unauthorized", "HTTP result code string");
                break;
            case 402:
                result = WEB_UI_STRING("payment required", "HTTP result code string");
                break;
            case 403:
                result = WEB_UI_STRING("forbidden", "HTTP result code string");
                break;
            case 404:
                result = WEB_UI_STRING("not found", "HTTP result code string");
                break;
            case 405:
                result = WEB_UI_STRING("method not allowed", "HTTP result code string");
                break;
            case 406:
                result = WEB_UI_STRING("unacceptable", "HTTP result code string");
                break;
            case 407:
                result = WEB_UI_STRING("proxy authentication required", "HTTP result code string");
                break;
            case 408:
                result = WEB_UI_STRING("request timed out", "HTTP result code string");
                break;
            case 409:
                result = WEB_UI_STRING("conflict", "HTTP result code string");
                break;
            case 410:
                result = WEB_UI_STRING("no longer exists", "HTTP result code string");
                break;
            case 411:
                result = WEB_UI_STRING("length required", "HTTP result code string");
                break;
            case 412:
                result = WEB_UI_STRING("precondition failed", "HTTP result code string");
                break;
            case 413:
                result = WEB_UI_STRING("request too large", "HTTP result code string");
                break;
            case 414:
                result = WEB_UI_STRING("requested URL too long", "HTTP result code string");
                break;
            case 415:
                result = WEB_UI_STRING("unsupported media type", "HTTP result code string");
                break;
            case 416:
                result = WEB_UI_STRING("requested range not satisfiable", "HTTP result code string");
                break;
            case 417:
                result = WEB_UI_STRING("expectation failed", "HTTP result code string");
                break;
            default:
                result = WEB_UI_STRING("client error", "HTTP result code string");
                break;
        }
    } else if (statusCode >= 500 && statusCode <= 599) {
        switch (statusCode) {
            case 500:
                result = WEB_UI_STRING("internal server error", "HTTP result code string");
                break;
            case 501:
                result = WEB_UI_STRING("unimplemented", "HTTP result code string");
                break;
            case 502:
                result = WEB_UI_STRING("bad gateway", "HTTP result code string");
                break;
            case 503:
                result = WEB_UI_STRING("service unavailable", "HTTP result code string");
                break;
            case 504:
                result = WEB_UI_STRING("gateway timed out", "HTTP result code string");
                break;
            case 505:
                result = WEB_UI_STRING("unsupported version", "HTTP result code string");
                break;
            default:
                result = WEB_UI_STRING("server error", "HTTP result code string");
                break;
        }
    }
    return result;
}

// IWebURLResponse ----------------------------------------------------------------

WebURLResponse::WebURLResponse()
{
    gClassCount++;
    gClassNameCount().add("WebURLResponse");
}

WebURLResponse::~WebURLResponse()
{
    gClassCount--;
    gClassNameCount().remove("WebURLResponse");
}

WebURLResponse* WebURLResponse::createInstance()
{
    WebURLResponse* instance = new WebURLResponse();
    // fake an http response - so it has the IWebHTTPURLResponse interface
    instance->m_response = ResourceResponse(WebCore::URL(ParsedURLString, "http://"), String(), 0, String());
    instance->AddRef();
    return instance;
}

WebURLResponse* WebURLResponse::createInstance(const ResourceResponse& response)
{
    if (response.isNull())
        return 0;

    WebURLResponse* instance = new WebURLResponse();
    instance->AddRef();
    instance->m_response = response;

    return instance;
}

// IUnknown -------------------------------------------------------------------

HRESULT WebURLResponse::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IWebURLResponse*>(this);
    else if (IsEqualGUID(riid, __uuidof(this)))
        *ppvObject = this;
    else if (IsEqualGUID(riid, IID_IWebURLResponse))
        *ppvObject = static_cast<IWebURLResponse*>(this);
    else if (IsEqualGUID(riid, IID_IWebURLResponsePrivate))
        *ppvObject = static_cast<IWebURLResponsePrivate*>(this);
    else if (m_response.isHTTP() && IsEqualGUID(riid, IID_IWebHTTPURLResponse))
        *ppvObject = static_cast<IWebHTTPURLResponse*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

ULONG WebURLResponse::AddRef()
{
    return ++m_refCount;
}

ULONG WebURLResponse::Release()
{
    ULONG newRef = --m_refCount;
    if (!newRef)
        delete(this);

    return newRef;
}

// IWebURLResponse --------------------------------------------------------------------

HRESULT WebURLResponse::expectedContentLength(_Out_ long long* result)
{
    if (!result)
        return E_POINTER;
    *result = m_response.expectedContentLength();
    return S_OK;
}

HRESULT WebURLResponse::initWithURL(_In_ BSTR url, _In_ BSTR mimeType, int expectedContentLength, _In_ BSTR textEncodingName)
{
    m_response = ResourceResponse(MarshallingHelpers::BSTRToKURL(url), String(mimeType), expectedContentLength, String(textEncodingName));
    return S_OK;
}

HRESULT WebURLResponse::MIMEType(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;

    BString mimeType(m_response.mimeType());
    *result = mimeType.release();
    if (!m_response.mimeType().isNull() && !*result)
        return E_OUTOFMEMORY;

    return S_OK;
}

HRESULT WebURLResponse::suggestedFilename(__deref_opt_out BSTR* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *result = nullptr;

    if (m_response.url().isEmpty())
        return E_FAIL;

    *result = BString(m_response.suggestedFilename()).release();
    return S_OK;
}

HRESULT WebURLResponse::textEncodingName(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_INVALIDARG;

    BString textEncodingName(m_response.textEncodingName());
    *result = textEncodingName.release();
    if (!m_response.textEncodingName().isNull() && !*result)
        return E_OUTOFMEMORY;

    return S_OK;
}

HRESULT WebURLResponse::URL(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_INVALIDARG;

    BString url(m_response.url().string());
    *result = url.release();
    if (!m_response.url().isEmpty() && !*result)
        return E_OUTOFMEMORY;

    return S_OK;
}

// IWebHTTPURLResponse --------------------------------------------------------

HRESULT WebURLResponse::allHeaderFields(_COM_Outptr_opt_ IPropertyBag** headerFields)
{
    ASSERT(m_response.isHTTP());

    if (!headerFields)
        return E_POINTER;

    HashMap<String, String, ASCIICaseInsensitiveHash> fields;
    for (const auto& keyValuePair : m_response.httpHeaderFields())
        fields.add(keyValuePair.key, keyValuePair.value);

    *headerFields = COMPropertyBag<String, String, ASCIICaseInsensitiveHash>::adopt(fields);
    return S_OK;
}

HRESULT WebURLResponse::localizedStringForStatusCode(int statusCode, __deref_opt_out BSTR* statusString)
{
    ASSERT(m_response.isHTTP());
    if (!statusString)
        return E_POINTER;

    *statusString = nullptr;
    const String& statusText = localizedShortDescriptionForStatusCode(statusCode);
    if (!statusText)
        return E_FAIL;
    *statusString = BString(statusText).release();
    return S_OK;
}

HRESULT WebURLResponse::statusCode(_Out_ int* statusCode)
{
    ASSERT(m_response.isHTTP());
    if (statusCode)
        *statusCode = m_response.httpStatusCode();
    return S_OK;
}

HRESULT WebURLResponse::isAttachment(_Out_ BOOL* attachment)
{
    if (!attachment)
        return E_POINTER;
    *attachment = m_response.isAttachment();
    return S_OK;
}

HRESULT WebURLResponse::sslPeerCertificate(_Out_ ULONG_PTR* result)
{
    if (!result)
        return E_POINTER;
    *result = 0;

#if USE(CFURLCONNECTION)
    CFDictionaryRef dict = certificateDictionary();
    if (!dict)
        return E_FAIL;
    void* data = wkGetSSLPeerCertificateDataBytePtr(dict);
    if (!data)
        return E_FAIL;
    *result = reinterpret_cast<ULONG_PTR>(data);
#endif

    return *result ? S_OK : E_FAIL;
}

// WebURLResponse -------------------------------------------------------------

HRESULT WebURLResponse::suggestedFileExtension(BSTR* result)
{
    if (!result)
        return E_POINTER;

    *result = nullptr;

    if (m_response.mimeType().isEmpty())
        return E_FAIL;

    BString mimeType(m_response.mimeType());
    HKEY key;
    LONG err = RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("MIME\\Database\\Content Type"), 0, KEY_QUERY_VALUE, &key);
    if (!err) {
        HKEY subKey;
        err = RegOpenKeyEx(key, mimeType, 0, KEY_QUERY_VALUE, &subKey);
        if (!err) {
            DWORD keyType = REG_SZ;
            WCHAR extension[MAX_PATH];
            DWORD keySize = sizeof(extension)/sizeof(extension[0]);
            err = RegQueryValueEx(subKey, TEXT("Extension"), 0, &keyType, (LPBYTE)extension, &keySize);
            if (!err && keyType != REG_SZ)
                err = ERROR_INVALID_DATA;
            if (err) {
                // fallback handlers
                if (!wcscmp(mimeType, L"text/html")) {
                    wcscpy(extension, L".html");
                    err = 0;
                } else if (!wcscmp(mimeType, L"application/xhtml+xml")) {
                    wcscpy(extension, L".xhtml");
                    err = 0;
                } else if (!wcscmp(mimeType, L"image/svg+xml")) {
                    wcscpy(extension, L".svg");
                    err = 0;
                }
            }
            if (!err) {
                *result = SysAllocString(extension);
                if (!*result)
                    err = ERROR_OUTOFMEMORY;
            }
            RegCloseKey(subKey);
        }
        RegCloseKey(key);
    }

    return HRESULT_FROM_WIN32(err);
}

const ResourceResponse& WebURLResponse::resourceResponse() const
{
    return m_response;
}

#if USE(CFURLCONNECTION)
CFDictionaryRef WebURLResponse::certificateDictionary() const
{
    if (m_SSLCertificateInfo)
        return m_SSLCertificateInfo.get();

    CFURLResponseRef cfResponse = m_response.cfURLResponse();
    if (!cfResponse)
        return nullptr;
    m_SSLCertificateInfo = wkGetSSLCertificateInfo(cfResponse);
    return m_SSLCertificateInfo.get();
}
#endif
