/*
 * Copyright (C) 2006-2018 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 <pal/spi/win/CFNetworkSPIWin.h>
#endif

#include <WebCore/BString.h>
#include <WebCore/LocalizedStrings.h>
#include <WebCore/ResourceError.h>
#include <WebCore/ResourceHandle.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <wchar.h>
#include <wtf/URL.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(WTF::URL({ }, "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.isInHTTPFamily() && 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.isInHTTPFamily());

    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.isInHTTPFamily());
    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.isInHTTPFamily());
    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;
    const void* data = ResourceError::getSSLPeerCertificateDataBytePtr(dict);
    if (!data)
        return E_FAIL;
    *result = reinterpret_cast<ULONG_PTR>(const_cast<void*>(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 = _CFURLResponseGetSSLCertificateContext(cfResponse);
    return m_SSLCertificateInfo.get();
}
#endif
