/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "tools/skiaserve/Response.h"

#include "tools/skiaserve/Request.h"

#include "include/core/SkData.h"
#include "include/core/SkString.h"
#include "tools/flags/CommandLineFlags.h"

#include "microhttpd.h"

static DEFINE_string(source, "https://debugger-assets.skia.org", "Where to load the web UI from.");

static SkString generate_template(SkString source) {
    SkString debuggerTemplate;
    debuggerTemplate.appendf(
        "<!DOCTYPE html>\n"
        "<html>\n"
        "<head>\n"
        "    <title>SkDebugger</title>\n"
        "    <meta charset='utf-8' />\n"
        "    <meta http-equiv='X-UA-Compatible' content='IE=egde,chrome=1'>\n"
        "    <meta name='viewport' content='width=device-width, initial-scale=1.0'>\n"
        "    <script src='%s/res/js/core.js' type='text/javascript' charset='utf-8'></script>\n"
        "    <link href='%s/res/vul/elements.html' rel='import' />\n"
        "    <link rel='shortcut icon' href='%s/res/img/favicon.ico' type='image/x-icon'/ >"
        "</head>\n"
        "<body class='fullbleed layout vertical'>\n"
            "  <debugger-app-sk>This is the app."
            "  </debugger-app-sk>\n"
        "</body>\n"
        "</html>", source.c_str(), source.c_str(), source.c_str());
    return debuggerTemplate;
}

namespace Response {
// SendOK just sends an empty response with a 200 OK status code.
int SendOK(MHD_Connection* connection) {
    const char* data = "";

    MHD_Response* response = MHD_create_response_from_buffer(strlen(data),
                                                             (void*)data,
                                                             MHD_RESPMEM_PERSISTENT);
    int ret = MHD_queue_response(connection, 200, response);
    MHD_destroy_response(response);
    return ret;
}

int SendError(MHD_Connection* connection, const char* msg) {
    MHD_Response* response = MHD_create_response_from_buffer(strlen(msg),
                                                             (void*) msg,
                                                             MHD_RESPMEM_PERSISTENT);
    int ret = MHD_queue_response(connection, 500, response);
    MHD_destroy_response(response);
    return ret;
}

int SendData(MHD_Connection* connection, const SkData* data, const char* type,
             bool setContentDisposition, const char* dispositionString) {
    MHD_Response* response = MHD_create_response_from_buffer(data->size(),
                                                             const_cast<void*>(data->data()),
                                                             MHD_RESPMEM_MUST_COPY);
    MHD_add_response_header(response, "Content-Type", type);

    if (setContentDisposition) {
        MHD_add_response_header(response, "Content-Disposition", dispositionString);
    }

    int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
    MHD_destroy_response(response);
    return ret;
}

int SendTemplate(MHD_Connection* connection, bool redirect, const char* redirectUrl) {
    SkString debuggerTemplate = generate_template(SkString(FLAGS_source[0]));

    MHD_Response* response = MHD_create_response_from_buffer(
        debuggerTemplate.size(),
        (void*) const_cast<char*>(debuggerTemplate.c_str()),
        MHD_RESPMEM_MUST_COPY);
    MHD_add_response_header (response, "Access-Control-Allow-Origin", "*");

    int status = MHD_HTTP_OK;

    if (redirect) {
        MHD_add_response_header (response, "Location", redirectUrl);
        status = MHD_HTTP_SEE_OTHER;
    }

    int ret = MHD_queue_response(connection, status, response);
    MHD_destroy_response(response);
    return ret;
}

} // namespace Response
