/*
 * Copyright (C) 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. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "config.h"
#include "ResourceLoadDelegate.h"

#include "DumpRenderTree.h"
#include "LayoutTestController.h"
#include <WebKit/WebKitCOMAPI.h>
#include <comutil.h>
#include <sstream>
#include <tchar.h>
#include <wtf/Vector.h>

using namespace std;

static inline wstring wstringFromBSTR(BSTR str)
{
    return wstring(str, ::SysStringLen(str));
}

static inline wstring wstringFromInt(int i)
{
    wostringstream ss;
    ss << i;
    return ss.str();
}

static inline BSTR BSTRFromString(const string& str)
{
    int length = ::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), 0, 0);
    BSTR result = ::SysAllocStringLen(0, length);
    ::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), result, length);
    return result;
}

wstring ResourceLoadDelegate::descriptionSuitableForTestResult(unsigned long identifier) const
{
    IdentifierMap::const_iterator it = m_urlMap.find(identifier);
    
    if (it == m_urlMap.end())
        return L"<unknown>";

    return urlSuitableForTestResult(it->second);
}

wstring ResourceLoadDelegate::descriptionSuitableForTestResult(IWebURLRequest* request)
{
    if (!request)
        return L"(null)";

    BSTR urlBSTR;
    if (FAILED(request->URL(&urlBSTR)))
        return wstring();
    
    wstring url = urlSuitableForTestResult(wstringFromBSTR(urlBSTR));
    ::SysFreeString(urlBSTR);
    
    BSTR mainDocumentURLBSTR;
    if (FAILED(request->mainDocumentURL(&mainDocumentURLBSTR)))
        return wstring();
    
    wstring mainDocumentURL = urlSuitableForTestResult(wstringFromBSTR(mainDocumentURLBSTR));
    ::SysFreeString(mainDocumentURLBSTR);
    
    BSTR httpMethodBSTR;
    if (FAILED(request->HTTPMethod(&httpMethodBSTR)))
        return wstring();
    
    wstring httpMethod = wstringFromBSTR(httpMethodBSTR);
    ::SysFreeString(httpMethodBSTR);

    return L"<NSURLRequest URL " + url + L", main document URL " + mainDocumentURL + L", http method " + httpMethod + L">";
}

wstring ResourceLoadDelegate::descriptionSuitableForTestResult(IWebURLResponse* response)
{
    if (!response)
        return L"(null)";

    BSTR urlBSTR;
    if (FAILED(response->URL(&urlBSTR)))
        return wstring();
    
    wstring url = urlSuitableForTestResult(wstringFromBSTR(urlBSTR));
    ::SysFreeString(urlBSTR);

    int statusCode = 0;
    COMPtr<IWebHTTPURLResponse> httpResponse;
    if (response && SUCCEEDED(response->QueryInterface(&httpResponse)))
        httpResponse->statusCode(&statusCode);
    
    return L"<NSURLResponse " + url + L", http status code " + wstringFromInt(statusCode) + L">";
}

wstring ResourceLoadDelegate::descriptionSuitableForTestResult(IWebError* error, unsigned long identifier) const
{
    wstring result = L"<NSError ";

    BSTR domainSTR;
    if (FAILED(error->domain(&domainSTR)))
        return wstring();

    wstring domain = wstringFromBSTR(domainSTR);
    ::SysFreeString(domainSTR);

    int code;
    if (FAILED(error->code(&code)))
        return wstring();

    if (domain == L"CFURLErrorDomain") {
        domain = L"NSURLErrorDomain";

        // Convert kCFURLErrorUnknown to NSURLErrorUnknown
        if (code == -998)
            code = -1;
    } else if (domain == L"kCFErrorDomainWinSock") {
        domain = L"NSURLErrorDomain";

        // Convert the winsock error code to an NSURLError code.
        if (code == WSAEADDRNOTAVAIL)
            code = -1004; // NSURLErrorCannotConnectToHose;
    }

    result += L"domain " + domain;
    result += L", code " + wstringFromInt(code);

    BSTR failingURLSTR;
    if (FAILED(error->failingURL(&failingURLSTR)))
        return wstring();

    wstring failingURL;
    
    // If the error doesn't have a failing URL, we fake one by using the URL the resource had 
    // at creation time. This seems to work fine for now.
    // See <rdar://problem/5064234> CFErrors should have failingURL key.
    if (failingURLSTR)
        failingURL = wstringFromBSTR(failingURLSTR);
    else
        failingURL = descriptionSuitableForTestResult(identifier);

    ::SysFreeString(failingURLSTR);

    result += L", failing URL \"" + urlSuitableForTestResult(failingURL) + L"\">";

    return result;
}

ResourceLoadDelegate::ResourceLoadDelegate()
    : m_refCount(1)
{
}

ResourceLoadDelegate::~ResourceLoadDelegate()
{
}

HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::QueryInterface(REFIID riid, void** ppvObject)
{
    *ppvObject = 0;
    if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IWebResourceLoadDelegate*>(this);
    else if (IsEqualGUID(riid, IID_IWebResourceLoadDelegate))
        *ppvObject = static_cast<IWebResourceLoadDelegate*>(this);
    else if (IsEqualGUID(riid, IID_IWebResourceLoadDelegatePrivate2))
        *ppvObject = static_cast<IWebResourceLoadDelegatePrivate2*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

ULONG STDMETHODCALLTYPE ResourceLoadDelegate::AddRef(void)
{
    return ++m_refCount;
}

ULONG STDMETHODCALLTYPE ResourceLoadDelegate::Release(void)
{
    ULONG newRef = --m_refCount;
    if (!newRef)
        delete(this);

    return newRef;
}

HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::identifierForInitialRequest( 
    /* [in] */ IWebView* webView,
    /* [in] */ IWebURLRequest* request,
    /* [in] */ IWebDataSource* dataSource,
    /* [in] */ unsigned long identifier)
{ 
    if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
        BSTR urlStr;
        if (FAILED(request->URL(&urlStr)))
            return E_FAIL;

        ASSERT(!urlMap().contains(identifier));
        urlMap().set(identifier, wstringFromBSTR(urlStr));
    }

    return S_OK;
}

HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::removeIdentifierForRequest(
    /* [in] */ IWebView* webView,
    /* [in] */ unsigned long identifier)
{
    urlMap().remove(identifier);

    return S_OK;
}

HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::willSendRequest( 
    /* [in] */ IWebView* webView,
    /* [in] */ unsigned long identifier,
    /* [in] */ IWebURLRequest* request,
    /* [in] */ IWebURLResponse* redirectResponse,
    /* [in] */ IWebDataSource* dataSource,
    /* [retval][out] */ IWebURLRequest **newRequest)
{
    if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
        printf("%S - willSendRequest %S redirectResponse %S\n", 
            descriptionSuitableForTestResult(identifier).c_str(),
            descriptionSuitableForTestResult(request).c_str(),
            descriptionSuitableForTestResult(redirectResponse).c_str());
    }

    if (!done && !gLayoutTestController->deferMainResourceDataLoad()) {
        COMPtr<IWebDataSourcePrivate> dataSourcePrivate(Query, dataSource);
        if (!dataSourcePrivate)
            return E_FAIL;
        dataSourcePrivate->setDeferMainResourceDataLoad(FALSE);
    }

    if (!done && gLayoutTestController->willSendRequestReturnsNull()) {
        *newRequest = 0;
        return S_OK;
    }

    if (!done && gLayoutTestController->willSendRequestReturnsNullOnRedirect() && redirectResponse) {
        printf("Returning null for this redirect\n");
        *newRequest = 0;
        return S_OK;
    }

    IWebMutableURLRequest* requestCopy = 0;
    request->mutableCopy(&requestCopy);
    const set<string>& clearHeaders = gLayoutTestController->willSendRequestClearHeaders();
    for (set<string>::const_iterator header = clearHeaders.begin(); header != clearHeaders.end(); ++header) {
      BSTR bstrHeader = BSTRFromString(*header);
      requestCopy->setValue(0, bstrHeader);
      SysFreeString(bstrHeader);
    }

    *newRequest = requestCopy;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didReceiveAuthenticationChallenge( 
    /* [in] */ IWebView *webView,
    /* [in] */ unsigned long identifier,
    /* [in] */ IWebURLAuthenticationChallenge *challenge,
    /* [in] */ IWebDataSource *dataSource)
{
    COMPtr<IWebURLAuthenticationChallengeSender> sender;
    if (!challenge || FAILED(challenge->sender(&sender)))
        return E_FAIL;

    if (!gLayoutTestController->handlesAuthenticationChallenges()) {
        printf("%S - didReceiveAuthenticationChallenge - Simulating cancelled authentication sheet\n", descriptionSuitableForTestResult(identifier).c_str());
        sender->continueWithoutCredentialForAuthenticationChallenge(challenge);
        return S_OK;
    }
    
    const char* user = gLayoutTestController->authenticationUsername().c_str();
    const char* password = gLayoutTestController->authenticationPassword().c_str();

    printf("%S - didReceiveAuthenticationChallenge - Responding with %s:%s\n", descriptionSuitableForTestResult(identifier).c_str(), user, password);

    COMPtr<IWebURLCredential> credential;
    if (FAILED(WebKitCreateInstance(CLSID_WebURLCredential, 0, IID_IWebURLCredential, (void**)&credential)))
        return E_FAIL;
    credential->initWithUser(_bstr_t(user), _bstr_t(password), WebURLCredentialPersistenceForSession);

    sender->useCredential(credential.get(), challenge);
    return S_OK;
}

HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didReceiveResponse(
    /* [in] */ IWebView* webView, 
    /* [in] */ unsigned long identifier, 
    /* [in] */ IWebURLResponse* response, 
    /* [in] */ IWebDataSource* dataSource)
{
    if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
        printf("%S - didReceiveResponse %S\n",
            descriptionSuitableForTestResult(identifier).c_str(),
            descriptionSuitableForTestResult(response).c_str());
    }
    if (!done && gLayoutTestController->dumpResourceResponseMIMETypes()) {
        BSTR mimeTypeBSTR;
        if (FAILED(response->MIMEType(&mimeTypeBSTR)))
            E_FAIL;
    
        wstring mimeType = wstringFromBSTR(mimeTypeBSTR);
        ::SysFreeString(mimeTypeBSTR);

        BSTR urlBSTR;
        if (FAILED(response->URL(&urlBSTR)))
            E_FAIL;
    
        wstring url = wstringFromBSTR(urlBSTR);
        ::SysFreeString(urlBSTR);

        printf("%S has MIME type %S\n", lastPathComponent(url).c_str(), mimeType.c_str());
    }

    return S_OK;
}


HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFinishLoadingFromDataSource( 
    /* [in] */ IWebView* webView,
    /* [in] */ unsigned long identifier,
    /* [in] */ IWebDataSource* dataSource)
{
    if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
        printf("%S - didFinishLoading\n",
            descriptionSuitableForTestResult(identifier).c_str());
    }

    removeIdentifierForRequest(webView, identifier);

    return S_OK;
}
        
HRESULT STDMETHODCALLTYPE ResourceLoadDelegate::didFailLoadingWithError( 
    /* [in] */ IWebView* webView,
    /* [in] */ unsigned long identifier,
    /* [in] */ IWebError* error,
    /* [in] */ IWebDataSource* dataSource)
{
    if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
        printf("%S - didFailLoadingWithError: %S\n", 
            descriptionSuitableForTestResult(identifier).c_str(),
            descriptionSuitableForTestResult(error, identifier).c_str());
    }

    removeIdentifierForRequest(webView, identifier);

    return S_OK;
}
