/*
 * 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/urlhandlers/UrlHandler.h"

#include "microhttpd.h"
#include "src/utils/SkJSONWriter.h"
#include "tools/debugger/DrawCommand.h"
#include "tools/skiaserve/Request.h"
#include "tools/skiaserve/Response.h"

using namespace Response;

bool BreakHandler::canHandle(const char* method, const char* url) {
    static const char* kBasePath = "/break";
    return 0 == strcmp(method, MHD_HTTP_METHOD_GET) &&
           0 == strncmp(url, kBasePath, strlen(kBasePath));
}

int BreakHandler::handle(Request* request, MHD_Connection* connection,
                         const char* url, const char* method,
                         const char* upload_data, size_t* upload_data_size) {
    SkTArray<SkString> commands;
    SkStrSplit(url, "/", &commands);

    if (!request->hasPicture() || commands.size() != 4) {
        return MHD_NO;
    }

    // /break/<n>/<x>/<y>
    int n;
    sscanf(commands[1].c_str(), "%d", &n);
    int x;
    sscanf(commands[2].c_str(), "%d", &x);
    int y;
    sscanf(commands[3].c_str(), "%d", &y);

    int count = request->fDebugCanvas->getSize();
    SkASSERT(n < count);

    SkCanvas* canvas = request->getCanvas();
    canvas->clear(SK_ColorWHITE);
    int saveCount = canvas->save();
    for (int i = 0; i <= n; ++i) {
        request->fDebugCanvas->getDrawCommandAt(i)->execute(canvas);
    }
    SkColor target = request->getPixel(x, y);

    SkDynamicMemoryWStream stream;
    SkJSONWriter writer(&stream, SkJSONWriter::Mode::kFast);
    writer.beginObject(); // root

    writer.appendName("startColor");
    DrawCommand::MakeJsonColor(writer, target);

    bool changed = false;
    for (int i = n + 1; i < n + count; ++i) {
        int index = i % count;
        if (index == 0) {
            // reset canvas for wraparound
            canvas->restoreToCount(saveCount);
            canvas->clear(SK_ColorWHITE);
            saveCount = canvas->save();
        }
        request->fDebugCanvas->getDrawCommandAt(index)->execute(canvas);
        SkColor current = request->getPixel(x, y);
        if (current != target) {
            writer.appendName("endColor");
            DrawCommand::MakeJsonColor(writer, current);
            writer.appendS32("endOp", index);
            changed = true;
            break;
        }
    }
    if (!changed) {
        writer.appendName("endColor");
        DrawCommand::MakeJsonColor(writer, target);
        writer.appendS32("endOp", n);
    }
    canvas->restoreToCount(saveCount);

    writer.endObject(); // root
    writer.flush();
    return SendData(connection, stream.detachAsData().get(), "application/json");
}
