/*
 * Copyright (C) 2006-2007, 2015 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 "WebKitDLL.h"
#include "WebMutableURLRequest.h"

#include "WebKit.h"
#include "MarshallingHelpers.h"
#include "WebKit.h"
#include <WebCore/BString.h>
#include <WebCore/COMPtr.h>
#include <WebCore/FormData.h>
#include <WebCore/ResourceHandle.h>
#include <wtf/text/CString.h>
#include <wtf/RetainPtr.h>

#if USE(CF)
#include <WebCore/CertificateCFWin.h>
#endif

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

using namespace WebCore;

// IWebURLRequest ----------------------------------------------------------------

WebMutableURLRequest::WebMutableURLRequest(bool isMutable)
    : m_isMutable(isMutable)
{
    gClassCount++;
    gClassNameCount().add("WebMutableURLRequest");
}

WebMutableURLRequest* WebMutableURLRequest::createInstance()
{
    WebMutableURLRequest* instance = new WebMutableURLRequest(true);
    instance->AddRef();
    return instance;
}

WebMutableURLRequest* WebMutableURLRequest::createInstance(IWebMutableURLRequest* req)
{
    WebMutableURLRequest* instance = new WebMutableURLRequest(true);
    instance->AddRef();
    instance->m_request = static_cast<WebMutableURLRequest*>(req)->m_request;
    return instance;
}

WebMutableURLRequest* WebMutableURLRequest::createInstance(const ResourceRequest& request)
{
    WebMutableURLRequest* instance = new WebMutableURLRequest(true);
    instance->AddRef();
    instance->m_request = request;
    return instance;
}

WebMutableURLRequest* WebMutableURLRequest::createImmutableInstance()
{
    WebMutableURLRequest* instance = new WebMutableURLRequest(false);
    instance->AddRef();
    return instance;
}

WebMutableURLRequest* WebMutableURLRequest::createImmutableInstance(const ResourceRequest& request)
{
    WebMutableURLRequest* instance = new WebMutableURLRequest(false);
    instance->AddRef();
    instance->m_request = request;
    return instance;
}

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

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

HRESULT WebMutableURLRequest::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, CLSID_WebMutableURLRequest))
        *ppvObject = this;
    else if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IWebURLRequest*>(this);
    else if (IsEqualGUID(riid, IID_IWebMutableURLRequest) && m_isMutable)
        *ppvObject = static_cast<IWebMutableURLRequest*>(this);
    else if (IsEqualGUID(riid, __uuidof(IWebMutableURLRequestPrivate)) && m_isMutable)
        *ppvObject = static_cast<IWebMutableURLRequestPrivate*>(this);
    else if (IsEqualGUID(riid, IID_IWebURLRequest))
        *ppvObject = static_cast<IWebURLRequest*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

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

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

    return newRef;
}

// IWebURLRequest --------------------------------------------------------------------

HRESULT WebMutableURLRequest::requestWithURL(_In_ BSTR /*theURL*/, WebURLRequestCachePolicy /*cachePolicy*/, double /*timeoutInterval*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

HRESULT WebMutableURLRequest::allHTTPHeaderFields(_COM_Outptr_opt_ IPropertyBag** result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}

HRESULT WebMutableURLRequest::cachePolicy(_Out_ WebURLRequestCachePolicy* result)
{
    if (!result)
        return E_POINTER;
    *result = kit(m_request.cachePolicy());
    return S_OK;
}

HRESULT WebMutableURLRequest::HTTPBody(_COM_Outptr_opt_ IStream** result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}

HRESULT WebMutableURLRequest::HTTPBodyStream(_COM_Outptr_opt_ IStream** result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}

HRESULT WebMutableURLRequest::HTTPMethod(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;
    BString httpMethod = BString(m_request.httpMethod());
    *result = httpMethod.release();
    return S_OK;
}

HRESULT WebMutableURLRequest::HTTPShouldHandleCookies(_Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;
    bool shouldHandleCookies = m_request.allowCookies();

    *result = shouldHandleCookies ? TRUE : FALSE;
    return S_OK;
}

HRESULT WebMutableURLRequest::initWithURL(_In_ BSTR url, WebURLRequestCachePolicy cachePolicy, double timeoutInterval)
{
    m_request.setURL(MarshallingHelpers::BSTRToKURL(url));
    m_request.setCachePolicy(core(cachePolicy));
    m_request.setTimeoutInterval(timeoutInterval);

    return S_OK;
}

HRESULT WebMutableURLRequest::mainDocumentURL(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;
    *result = MarshallingHelpers::URLToBSTR(m_request.firstPartyForCookies());
    return S_OK;
}

HRESULT WebMutableURLRequest::timeoutInterval(_Out_ double* result)
{
    if (!result)
        return E_POINTER;
    *result = m_request.timeoutInterval();
    return S_OK;
}

HRESULT WebMutableURLRequest::URL(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;
    *result = MarshallingHelpers::URLToBSTR(m_request.url());
    return S_OK;
}

HRESULT WebMutableURLRequest::valueForHTTPHeaderField(_In_ BSTR field, __deref_opt_out BSTR* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *result = BString(m_request.httpHeaderField(String(field, SysStringLen(field)))).release();
    return S_OK;
}

HRESULT WebMutableURLRequest::isEmpty(_Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;
    *result = m_request.isEmpty();
    return S_OK;
}

HRESULT WebMutableURLRequest::isEqual(_In_opt_ IWebURLRequest* other, _Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;

    COMPtr<WebMutableURLRequest> requestImpl(Query, other);

    if (!requestImpl) {
        *result = FALSE;
        return S_OK;
    }

    *result = m_request == requestImpl->resourceRequest();
    return S_OK;
}


// IWebMutableURLRequest --------------------------------------------------------

HRESULT WebMutableURLRequest::addValue(_In_ BSTR value, _In_ BSTR field)
{
    m_request.addHTTPHeaderField(WTF::AtomicString(value, SysStringLen(value)), String(field, SysStringLen(field)));
    return S_OK;
}

HRESULT WebMutableURLRequest::setAllHTTPHeaderFields(_In_opt_ IPropertyBag* /*headerFields*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

HRESULT WebMutableURLRequest::setCachePolicy(WebURLRequestCachePolicy policy)
{
    m_request.setCachePolicy(core(policy));
    return S_OK;
}

HRESULT WebMutableURLRequest::setHTTPBody(_In_opt_ IStream* data)
{
    if (!data)
        return E_POINTER;

    STATSTG stat;
    if (FAILED(data->Stat(&stat, STATFLAG_NONAME)))
        return E_FAIL;

    if (stat.cbSize.HighPart || !stat.cbSize.LowPart)
        return E_FAIL;

    RefPtr<FormData> httpBody = FormData::create();
    char* formData = httpBody->expandDataStore(stat.cbSize.LowPart);

    ULONG bytesRead = 0;
    if (FAILED(data->Read(formData, stat.cbSize.LowPart, &bytesRead)))
        return E_FAIL;

    m_request.setHTTPBody(WTFMove(httpBody));
    return S_OK;
}

HRESULT WebMutableURLRequest::setHTTPBodyStream(_In_opt_ IStream* data)
{
    return setHTTPBody(data);
}

HRESULT WebMutableURLRequest::setHTTPMethod(_In_ BSTR method)
{
    m_request.setHTTPMethod(String(method));
    return S_OK;
}

HRESULT WebMutableURLRequest::setHTTPShouldHandleCookies(BOOL handleCookies)
{
    m_request.setAllowCookies(handleCookies);
    return S_OK;
}

HRESULT WebMutableURLRequest::setMainDocumentURL(_In_ BSTR theURL)
{
    m_request.setFirstPartyForCookies(MarshallingHelpers::BSTRToKURL(theURL));
    return S_OK;
}

HRESULT WebMutableURLRequest::setTimeoutInterval(double timeoutInterval)
{
    m_request.setTimeoutInterval(timeoutInterval);
    return S_OK;
}

HRESULT WebMutableURLRequest::setURL(_In_ BSTR url)
{
    m_request.setURL(MarshallingHelpers::BSTRToKURL(url));
    return S_OK;
}

HRESULT WebMutableURLRequest::setValue(_In_ BSTR value, _In_ BSTR field)
{
    String valueString(value, SysStringLen(value));
    String fieldString(field, SysStringLen(field));
    m_request.setHTTPHeaderField(fieldString, valueString);
    return S_OK;
}

HRESULT WebMutableURLRequest::setAllowsAnyHTTPSCertificate()
{
    ResourceHandle::setHostAllowsAnyHTTPSCertificate(m_request.url().host());

    return S_OK;
}

HRESULT WebMutableURLRequest::setClientCertificate(ULONG_PTR cert)
{
    if (!cert)
        return E_POINTER;

    PCCERT_CONTEXT certContext = reinterpret_cast<PCCERT_CONTEXT>(cert);
    RetainPtr<CFDataRef> certData = WebCore::copyCertificateToData(certContext);
    ResourceHandle::setClientCertificate(m_request.url().host(), certData.get());
    return S_OK;
}

CFURLRequestRef WebMutableURLRequest::cfRequest()
{
    return m_request.cfURLRequest(UpdateHTTPBody);
}

HRESULT WebMutableURLRequest::mutableCopy(_COM_Outptr_opt_ IWebMutableURLRequest** result)
{
    if (!result)
        return E_POINTER;

#if USE(CFURLCONNECTION)
    RetainPtr<CFMutableURLRequestRef> mutableRequest = adoptCF(CFURLRequestCreateMutableCopy(kCFAllocatorDefault, m_request.cfURLRequest(UpdateHTTPBody)));
    *result = createInstance(ResourceRequest(mutableRequest.get()));
    return S_OK;
#else
    *result = createInstance(m_request);
    return S_OK;
#endif
}

// IWebMutableURLRequest ----------------------------------------------------

void WebMutableURLRequest::setFormData(RefPtr<FormData>&& data)
{
    m_request.setHTTPBody(WTFMove(data));
}

const RefPtr<FormData> WebMutableURLRequest::formData() const
{
    return m_request.httpBody();
}

const HTTPHeaderMap& WebMutableURLRequest::httpHeaderFields() const
{
    return m_request.httpHeaderFields();
}

const ResourceRequest& WebMutableURLRequest::resourceRequest() const
{
    return m_request;
}
