/*
 * Copyright 2008, 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 "wds"
#include "config.h"

#include "AndroidLog.h"
#include "Command.h"
#include "Connection.h"
#include "DebugServer.h"
#include "Frame.h"
#include "RenderTreeAsText.h"
#include "RenderView.h"
#include "WebViewCore.h"
#include <utils/Log.h>
#include <wtf/text/CString.h>

#if ENABLE(WDS)

using namespace WebCore;

namespace android {

namespace WDS {

//------------------------------------------------------------------------------
// Actual commands -- XXX should be moved somewhere else
//------------------------------------------------------------------------------
static bool callDumpRenderTree(const Frame* frame, const Connection* conn) {
    CString str = externalRepresentation(frame->contentRenderer()).latin1();
    conn->write(str.data(), str.length());
    return true;
}

static bool callDumpDomTree(const Frame* frame, const Connection* conn) {
    WebViewCore::getWebViewCore(frame->view())->dumpDomTree(true);

    FILE* f = fopen(DOM_TREE_LOG_FILE, "r");
    if (!f) {
        conn->write("Dom tree written to logcat\n");
    } else {
        char buf[512];
        while (true) {
            int nread = fread(buf, 1, sizeof(buf), f);
            if (nread <= 0)
                break;
            conn->write(buf, nread);
        }
        fclose(f);
    }
    return true;
}

class WebCoreHandler : public Handler {
public:
    virtual void post(TargetThreadFunction func, void* v) const {
        callOnMainThread(func, v);
    }
};
static WebCoreHandler s_webcoreHandler;

//------------------------------------------------------------------------------
// End command section
//------------------------------------------------------------------------------

class InternalCommand : public Command {
public:
    InternalCommand(const Command* comm, const Frame* frame,
            const Connection* connection)
        : Command(*comm)
        , m_frame(frame)
        , m_connection(connection) {}
    virtual ~InternalCommand() { delete m_connection; }

    void doCommand() const {
        ALOGD("Executing command '%s' (%s)", m_name, m_description);
        if (!m_dispatch(m_frame, m_connection))
            // XXX: Have useful failure messages
            m_connection->write("EPIC FAIL!\n", 11);
    }

private:
    const Frame* m_frame;
    const Connection* m_connection;
};

static void commandDispatcher(void* v) {
    InternalCommand* c = static_cast<InternalCommand*>(v);
    c->doCommand();
    delete c;
}

void Command::dispatch() {
    m_handler.post(commandDispatcher, this);
}

Vector<const Command*>* Command::s_commands;

void Command::Init() {
    // Do not initialize twice.
    if (s_commands)
        return;
    // XXX: Move this somewhere else.
    s_commands = new Vector<const Command*>();
    s_commands->append(new Command("DDOM", "Dump Dom Tree",
                callDumpDomTree, s_webcoreHandler));
    s_commands->append(new Command("DDRT", "Dump Render Tree",
                callDumpRenderTree, s_webcoreHandler));
}

Command* Command::Find(const Connection* conn) {
    char buf[COMMAND_LENGTH];
    if (conn->read(buf, sizeof(buf)) != COMMAND_LENGTH)
        return NULL;

    // Linear search of commands. TODO: binary search when more commands are
    // added.
    Vector<const Command*>::const_iterator i = s_commands->begin();
    Vector<const Command*>::const_iterator end = s_commands->end();
    while (i != end) {
        if (strncmp(buf, (*i)->name(), sizeof(buf)) == 0)
            return new InternalCommand(*i, server()->getFrame(0), conn);
        i++;
    }
    return NULL;
}

} // end namespace WDS

} // end namespace android

#endif
