/*
 * Copyright 2010, The Android Open Source Project
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * 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 THE COPYRIGHT HOLDERS ``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 THE COPYRIGHT OWNER 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.
 */

#define LOG_TAG "webarchive"

#include "config.h"
#include "WebArchiveAndroid.h"

#if ENABLE(WEB_ARCHIVE)

#include "Base64.h"
#include <libxml/encoding.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlstring.h>
#include <libxml/xmlwriter.h>
#include <utils/Log.h>
#include <wtf/text/CString.h>

namespace WebCore {

static const xmlChar* const archiveTag = BAD_CAST "Archive";
static const xmlChar* const archiveResourceTag = BAD_CAST "ArchiveResource";
static const xmlChar* const mainResourceTag = BAD_CAST "mainResource";
static const xmlChar* const subresourcesTag = BAD_CAST "subresources";
static const xmlChar* const subframesTag = BAD_CAST "subframes";
static const xmlChar* const urlFieldTag = BAD_CAST "url";
static const xmlChar* const mimeFieldTag = BAD_CAST "mimeType";
static const xmlChar* const encodingFieldTag = BAD_CAST "textEncoding";
static const xmlChar* const frameFieldTag = BAD_CAST "frameName";
static const xmlChar* const dataFieldTag = BAD_CAST "data";

PassRefPtr<WebArchiveAndroid> WebArchiveAndroid::create(PassRefPtr<ArchiveResource> mainResource,
        Vector<PassRefPtr<ArchiveResource> >& subresources,
        Vector<PassRefPtr<Archive> >& subframeArchives)
{
    if (mainResource)
        return adoptRef(new WebArchiveAndroid(mainResource, subresources, subframeArchives));
    return 0;
}

PassRefPtr<WebArchiveAndroid> WebArchiveAndroid::create(Frame* frame)
{
    PassRefPtr<ArchiveResource> mainResource = frame->loader()->documentLoader()->mainResource();
    Vector<PassRefPtr<ArchiveResource> > subresources;
    Vector<PassRefPtr<Archive> > subframes;
    int children = frame->tree()->childCount();

    frame->loader()->documentLoader()->getSubresources(subresources);

    for (int child = 0; child < children; child++)
        subframes.append(create(frame->tree()->child(child)));

    return create(mainResource, subresources, subframes);
}

WebArchiveAndroid::WebArchiveAndroid(PassRefPtr<ArchiveResource> mainResource,
        Vector<PassRefPtr<ArchiveResource> >& subresources,
        Vector<PassRefPtr<Archive> >& subframeArchives)
{
    setMainResource(mainResource);

    for (Vector<PassRefPtr<ArchiveResource> >::iterator subresourcesIterator = subresources.begin();
         subresourcesIterator != subresources.end();
         subresourcesIterator++) {
        addSubresource(*subresourcesIterator);
    }

    for (Vector<PassRefPtr<Archive> >::iterator subframesIterator = subframeArchives.begin();
         subframesIterator != subframeArchives.end();
         subframesIterator++) {
        addSubframeArchive(*subframesIterator);
    }
}

static bool loadArchiveResourceField(xmlNodePtr resourceNode, const xmlChar* fieldName, Vector<char>* outputData)
{
    if (!outputData)
        return false;

    outputData->clear();

    const char* base64Data = 0;

    for (xmlNodePtr fieldNode = resourceNode->xmlChildrenNode;
         fieldNode;
         fieldNode = fieldNode->next) {
        if (xmlStrEqual(fieldNode->name, fieldName)) {
            base64Data = (const char*)xmlNodeGetContent(fieldNode->xmlChildrenNode);
            if (!base64Data) {
                /* Empty fields seem to break if they aren't null terminated. */
                outputData->append('\0');
                return true;
            }
            break;
        }
    }
    if (!base64Data) {
        ALOGD("loadArchiveResourceField: Failed to load field.");
        return false;
    }

    const int base64Size = xmlStrlen(BAD_CAST base64Data);

    const int result = base64Decode(base64Data, base64Size, *outputData);
    if (!result) {
        ALOGD("loadArchiveResourceField: Failed to decode field.");
        return false;
    }

    return true;
}

static PassRefPtr<SharedBuffer> loadArchiveResourceFieldBuffer(xmlNodePtr resourceNode, const xmlChar* fieldName)
{
    Vector<char> fieldData;

    if (loadArchiveResourceField(resourceNode, fieldName, &fieldData))
        return SharedBuffer::create(fieldData.data(), fieldData.size());

    return 0;
}

static String loadArchiveResourceFieldString(xmlNodePtr resourceNode, const xmlChar* fieldName)
{
    Vector<char> fieldData;

    if (loadArchiveResourceField(resourceNode, fieldName, &fieldData))
        return String::fromUTF8(fieldData.data(), fieldData.size());

    return String();
}

static KURL loadArchiveResourceFieldURL(xmlNodePtr resourceNode, const xmlChar* fieldName)
{
    Vector<char> fieldData;

    if (loadArchiveResourceField(resourceNode, fieldName, &fieldData))
        return KURL(ParsedURLString, String::fromUTF8(fieldData.data(), fieldData.size()));

    return KURL();
}

static PassRefPtr<ArchiveResource> loadArchiveResource(xmlNodePtr resourceNode)
{
    if (!xmlStrEqual(resourceNode->name, archiveResourceTag)) {
        ALOGD("loadArchiveResource: Malformed resource.");
        return 0;
    }

    KURL url = loadArchiveResourceFieldURL(resourceNode, urlFieldTag);
    if (url.isNull()) {
        ALOGD("loadArchiveResource: Failed to load resource.");
        return 0;
    }

    String mimeType = loadArchiveResourceFieldString(resourceNode, mimeFieldTag);
    if (mimeType.isNull()) {
        ALOGD("loadArchiveResource: Failed to load resource.");
        return 0;
    }

    String textEncoding = loadArchiveResourceFieldString(resourceNode, encodingFieldTag);
    if (textEncoding.isNull()) {
        ALOGD("loadArchiveResource: Failed to load resource.");
        return 0;
    }

    String frameName = loadArchiveResourceFieldString(resourceNode, frameFieldTag);
    if (frameName.isNull()) {
        ALOGD("loadArchiveResource: Failed to load resource.");
        return 0;
    }

    PassRefPtr<SharedBuffer> data = loadArchiveResourceFieldBuffer(resourceNode, dataFieldTag);
    if (!data) {
        ALOGD("loadArchiveResource: Failed to load resource.");
        return 0;
    }

    return ArchiveResource::create(data, url, mimeType, textEncoding, frameName);
}

static PassRefPtr<WebArchiveAndroid> loadArchive(xmlNodePtr archiveNode)
{
    xmlNodePtr resourceNode = 0;

    PassRefPtr<ArchiveResource> mainResource;
    Vector<PassRefPtr<ArchiveResource> > subresources;
    Vector<PassRefPtr<Archive> > subframes;

    if (!xmlStrEqual(archiveNode->name, archiveTag)) {
        ALOGD("loadArchive: Malformed archive.");
        return 0;
    }

    for (resourceNode = archiveNode->xmlChildrenNode;
         resourceNode;
         resourceNode = resourceNode->next) {
        if (xmlStrEqual(resourceNode->name, mainResourceTag)) {
            resourceNode = resourceNode->xmlChildrenNode;
            if (!resourceNode)
                break;
            mainResource = loadArchiveResource(resourceNode);
            break;
        }
    }
    if (!mainResource) {
        ALOGD("loadArchive: Failed to load main resource.");
        return 0;
    }

    for (resourceNode = archiveNode->xmlChildrenNode;
         resourceNode;
         resourceNode = resourceNode->next) {
        if (xmlStrEqual(resourceNode->name, subresourcesTag)) {
            for (resourceNode = resourceNode->xmlChildrenNode;
                 resourceNode;
                 resourceNode = resourceNode->next) {
                PassRefPtr<ArchiveResource> subresource = loadArchiveResource(resourceNode);
                if (!subresource) {
                    ALOGD("loadArchive: Failed to load subresource.");
                    break;
                }
                subresources.append(subresource);
            }
            break;
        }
    }

    for (resourceNode = archiveNode->xmlChildrenNode;
         resourceNode;
         resourceNode = resourceNode->next) {
        if (xmlStrEqual(resourceNode->name, subframesTag)) {
            for (resourceNode = resourceNode->xmlChildrenNode;
                 resourceNode;
                 resourceNode = resourceNode->next) {
                PassRefPtr<WebArchiveAndroid> subframe = loadArchive(resourceNode);
                if (!subframe) {
                    ALOGD("loadArchive: Failed to load subframe.");
                    break;
                }
                subframes.append(subframe);
            }
            break;
        }
    }

    return WebArchiveAndroid::create(mainResource, subresources, subframes);
}

static PassRefPtr<WebArchiveAndroid> createArchiveForError()
{
    /* When an archive cannot be loaded, we return an empty archive instead. */
    PassRefPtr<ArchiveResource> mainResource = ArchiveResource::create(
        SharedBuffer::create(), KURL(ParsedURLString, String::fromUTF8("file:///dummy")),
        String::fromUTF8("text/plain"), String(""), String(""));
    Vector<PassRefPtr<ArchiveResource> > subresources;
    Vector<PassRefPtr<Archive> > subframes;

    return WebArchiveAndroid::create(mainResource, subresources, subframes);
}

PassRefPtr<WebArchiveAndroid> WebArchiveAndroid::create(SharedBuffer* buffer)
{
    const char* const noBaseUrl = "";
    const char* const defaultEncoding = 0;
    const int noParserOptions = 0;

    xmlDocPtr doc = xmlReadMemory(buffer->data(), buffer->size(), noBaseUrl, defaultEncoding, noParserOptions);
    if (!doc) {
        ALOGD("create: Failed to parse document.");
        return createArchiveForError();
    }

    xmlNodePtr root = xmlDocGetRootElement(doc);
    if (!root) {
        ALOGD("create: Empty document.");
        xmlFreeDoc(doc);
        return createArchiveForError();
    }

    RefPtr<WebArchiveAndroid> archive = loadArchive(root);
    if (!archive) {
        ALOGD("create: Failed to load archive.");
        xmlFreeDoc(doc);
        return createArchiveForError();
    }

    xmlFreeDoc(doc);
    return archive.release();
}

static bool saveArchiveResourceField(xmlTextWriterPtr writer, const xmlChar* tag, const char* data, int size)
{
    int result = xmlTextWriterStartElement(writer, tag);
    if (result < 0) {
        ALOGD("saveArchiveResourceField: Failed to start element.");
        return false;
    }

    if (size > 0) {
        Vector<char> base64Data;
        base64Encode(data, size, base64Data, false);
        if (base64Data.isEmpty()) {
            ALOGD("saveArchiveResourceField: Failed to base64 encode data.");
            return false;
        }

        result = xmlTextWriterWriteRawLen(writer, BAD_CAST base64Data.data(), base64Data.size());
        if (result < 0) {
            ALOGD("saveArchiveResourceField: Failed to write data.");
            return false;
        }
    }

    result = xmlTextWriterEndElement(writer);
    if (result < 0) {
        ALOGD("saveArchiveResourceField: Failed to end element.");
        return false;
    }

    return true;
}

static bool saveArchiveResourceField(xmlTextWriterPtr writer, const xmlChar* tag, SharedBuffer* buffer)
{
    return saveArchiveResourceField(writer, tag, buffer->data(), buffer->size());
}

static bool saveArchiveResourceField(xmlTextWriterPtr writer, const xmlChar* tag, const String& string)
{
    CString utf8String = string.utf8();

    return saveArchiveResourceField(writer, tag, utf8String.data(), utf8String.length());
}

static bool saveArchiveResource(xmlTextWriterPtr writer, PassRefPtr<ArchiveResource> resource)
{
    int result = xmlTextWriterStartElement(writer, archiveResourceTag);
    if (result < 0) {
        ALOGD("saveArchiveResource: Failed to start element.");
        return false;
    }

    if (!saveArchiveResourceField(writer, urlFieldTag, resource->url().string())
        || !saveArchiveResourceField(writer, mimeFieldTag, resource->mimeType())
        || !saveArchiveResourceField(writer, encodingFieldTag, resource->textEncoding())
        || !saveArchiveResourceField(writer, frameFieldTag, resource->frameName())
        || !saveArchiveResourceField(writer, dataFieldTag, resource->data()))
        return false;

    result = xmlTextWriterEndElement(writer);
    if (result < 0) {
        ALOGD("saveArchiveResource: Failed to end element.");
        return false;
    }

    return true;
}

static bool saveArchive(xmlTextWriterPtr writer, PassRefPtr<Archive> archive)
{
    int result = xmlTextWriterStartElement(writer, archiveTag);
    if (result < 0) {
        ALOGD("saveArchive: Failed to start element.");
        return false;
    }

    result = xmlTextWriterStartElement(writer, mainResourceTag);
    if (result < 0) {
        ALOGD("saveArchive: Failed to start element.");
        return false;
    }

    if (!saveArchiveResource(writer, archive->mainResource()))
        return false;

    result = xmlTextWriterEndElement(writer);
    if (result < 0) {
        ALOGD("saveArchive: Failed to end element.");
        return false;
    }

    result = xmlTextWriterStartElement(writer, subresourcesTag);
    if (result < 0) {
        ALOGD("saveArchive: Failed to start element.");
        return false;
    }

    for (Vector<const RefPtr<ArchiveResource> >::iterator subresource = archive->subresources().begin();
         subresource != archive->subresources().end();
         subresource++) {
        if (!saveArchiveResource(writer, *subresource))
            return false;
    }

    result = xmlTextWriterEndElement(writer);
    if (result < 0) {
        ALOGD("saveArchive: Failed to end element.");
        return false;
    }

    result = xmlTextWriterStartElement(writer, subframesTag);
    if (result < 0) {
        ALOGD("saveArchive: Failed to start element.");
        return false;
    }

    for (Vector<const RefPtr<Archive> >::iterator subframe = archive->subframeArchives().begin();
            subframe != archive->subframeArchives().end();
            subframe++) {
        if (!saveArchive(writer, *subframe))
            return false;
    }

    result = xmlTextWriterEndElement(writer);
    if (result < 0) {
        ALOGD("saveArchive: Failed to end element.");
        return true;
    }

    return true;
}

bool WebArchiveAndroid::saveWebArchive(xmlTextWriterPtr writer)
{
    const char* const defaultXmlVersion = 0;
    const char* const defaultEncoding = 0;
    const char* const defaultStandalone = 0;

    int result = xmlTextWriterStartDocument(writer, defaultXmlVersion, defaultEncoding, defaultStandalone);
    if (result < 0) {
        ALOGD("saveWebArchive: Failed to start document.");
        return false;
    }

    if (!saveArchive(writer, this))
        return false;

    result = xmlTextWriterEndDocument(writer);
    if (result< 0) {
        ALOGD("saveWebArchive: Failed to end document.");
        return false;
    }

    return true;
}

}

#endif // ENABLE(WEB_ARCHIVE)
