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

#include "gm_knowledge.h"

#include <cfloat>
#include <cstdlib>
#include <fstream>
#include <mutex>
#include <sstream>
#include <string>
#include <vector>

#include "../../src/core/SkStreamPriv.h"
#include "../../src/core/SkTSort.h"
#include "SkBitmap.h"
#include "SkCodec.h"
#include "SkOSFile.h"
#include "SkOSPath.h"
#include "SkPngEncoder.h"
#include "SkStream.h"

#include "skqp_asset_manager.h"

#define IMAGES_DIRECTORY_PATH "images"
#define PATH_MAX_PNG "max.png"
#define PATH_MIN_PNG "min.png"
#define PATH_IMG_PNG "image.png"
#define PATH_ERR_PNG "errors.png"
#define PATH_REPORT  "report.html"
#define PATH_CSV     "out.csv"

#ifndef SK_SKQP_GLOBAL_ERROR_TOLERANCE
#define SK_SKQP_GLOBAL_ERROR_TOLERANCE 0
#endif

#ifndef SK_SKQP_BADNESS_TOLERANCE
#define SK_SKQP_BADNESS_TOLERANCE 100
#endif


////////////////////////////////////////////////////////////////////////////////

static int get_error(uint32_t value, uint32_t value_max, uint32_t value_min) {
    int error = 0;
    for (int j : {0, 8, 16, 24}) {
        uint8_t    v = (value     >> j) & 0xFF,
                vmin = (value_min >> j) & 0xFF,
                vmax = (value_max >> j) & 0xFF;
        if (v > vmax) {
            error = std::max(v - vmax, error);
        } else if (v < vmin) {
            error = std::max(vmin - v, error);
        }
    }
    return std::max(0, error - SK_SKQP_GLOBAL_ERROR_TOLERANCE);
}

static int get_error_with_nearby(int x, int y, const SkPixmap& pm,
                                 const SkPixmap& pm_max, const SkPixmap& pm_min) {
    struct NearbyPixels {
        const int x, y, w, h;
        struct Iter {
            const int x, y, w, h;
            int8_t curr;
            SkIPoint operator*() const { return this->get(); }
            SkIPoint get() const {
                switch (curr) {
                    case 0: return {x - 1, y - 1};
                    case 1: return {x    , y - 1};
                    case 2: return {x + 1, y - 1};
                    case 3: return {x - 1, y    };
                    case 4: return {x + 1, y    };
                    case 5: return {x - 1, y + 1};
                    case 6: return {x    , y + 1};
                    case 7: return {x + 1, y + 1};
                    default: SkASSERT(false); return {0, 0};
                }
            }
            void skipBad() {
                while (curr < 8) {
                    SkIPoint p = this->get();
                    if (p.x() >= 0 && p.y() >= 0 && p.x() < w && p.y() < h) {
                        return;
                    }
                    ++curr;
                }
                curr = -1;
            }
            void operator++() {
                if (-1 == curr) { return; }
                ++curr;
                this->skipBad();
            }
            bool operator!=(const Iter& other) const { return curr != other.curr; }
        };
        Iter begin() const { Iter i{x, y, w, h, 0}; i.skipBad(); return i; }
        Iter end() const { return Iter{x, y, w, h, -1}; }
    };

    uint32_t c = *pm.addr32(x, y);
    int error = get_error(c, *pm_max.addr32(x, y), *pm_min.addr32(x, y));
    for (SkIPoint p : NearbyPixels{x, y, pm.width(), pm.height()}) {
        if (error == 0) {
            return 0;
        }
        error = SkTMin(error, get_error(
                    c, *pm_max.addr32(p.x(), p.y()), *pm_min.addr32(p.x(), p.y())));
    }
    return error;
}

static float set_error_code(gmkb::Error* error_out, gmkb::Error error) {
    SkASSERT(error != gmkb::Error::kNone);
    if (error_out) {
        *error_out = error;
    }
    return FLT_MAX;
}

static bool WritePixmapToFile(const SkPixmap& pixmap, const char* path) {
    SkFILEWStream wStream(path);
    SkPngEncoder::Options options;
    options.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore;
    return wStream.isValid() && SkPngEncoder::Encode(&wStream, pixmap, options);
}

constexpr SkColorType kColorType = kRGBA_8888_SkColorType;
constexpr SkAlphaType kAlphaType = kUnpremul_SkAlphaType;

static SkPixmap rgba8888_to_pixmap(const uint32_t* pixels, int width, int height) {
    SkImageInfo info = SkImageInfo::Make(width, height, kColorType, kAlphaType);
    return SkPixmap(info, pixels, width * sizeof(uint32_t));
}

static bool copy(skqp::AssetManager* mgr, const char* path, const char* dst) {
    if (mgr) {
        if (auto stream = mgr->open(path)) {
            SkFILEWStream wStream(dst);
            return wStream.isValid() && SkStreamCopy(&wStream, stream.get());
        }
    }
    return false;
}

static SkBitmap ReadPngRgba8888FromFile(skqp::AssetManager* assetManager, const char* path) {
    SkBitmap bitmap;
    if (auto codec = SkCodec::MakeFromStream(assetManager->open(path))) {
        SkISize size = codec->getInfo().dimensions();
        SkASSERT(!size.isEmpty());
        SkImageInfo info = SkImageInfo::Make(size.width(), size.height(), kColorType, kAlphaType);
        bitmap.allocPixels(info);
        SkASSERT(bitmap.rowBytes() == (unsigned)bitmap.width() * sizeof(uint32_t));
        if (SkCodec::kSuccess != codec->getPixels(bitmap.pixmap())) {
            bitmap.reset();
        }
    }
    return bitmap;
}

namespace {
struct Run {
    SkString fBackend;
    SkString fGM;
    int fMaxerror;
    int fBadpixels;
};
}  // namespace

static std::vector<Run> gErrors;
static std::mutex gMutex;

static SkString make_path(const SkString& images_directory,
                          const char* backend,
                          const char* gm_name,
                          const char* thing) {
    auto path = SkStringPrintf("%s_%s_%s", backend, gm_name, thing);
    return SkOSPath::Join(images_directory.c_str(), path.c_str());
}


namespace gmkb {
float Check(const uint32_t* pixels,
            int width,
            int height,
            const char* name,
            const char* backend,
            skqp::AssetManager* assetManager,
            const char* report_directory_path,
            Error* error_out) {
    if (report_directory_path && report_directory_path[0]) {
        SkASSERT_RELEASE(sk_isdir(report_directory_path));
    }
    if (width <= 0 || height <= 0) {
        return set_error_code(error_out, Error::kBadInput);
    }
    constexpr char PATH_ROOT[] = "gmkb";
    SkString img_path = SkOSPath::Join(PATH_ROOT, name);
    SkString max_path = SkOSPath::Join(img_path.c_str(), PATH_MAX_PNG);
    SkString min_path = SkOSPath::Join(img_path.c_str(), PATH_MIN_PNG);
    SkBitmap max_image = ReadPngRgba8888FromFile(assetManager, max_path.c_str());
    SkBitmap min_image = ReadPngRgba8888FromFile(assetManager, min_path.c_str());
    if (max_image.isNull() || min_image.isNull()) {
        // No data.
        if (error_out) {
            *error_out = Error::kNone;
        }
        return 0;
    }
    if (max_image.width()  != min_image.width() ||
        max_image.height() != min_image.height())
    {
        return set_error_code(error_out, Error::kBadData);
    }
    if (max_image.width() != width || max_image.height() != height) {
        return set_error_code(error_out, Error::kBadInput);
    }

    int badness = 0;
    int badPixelCount = 0;
    SkPixmap pm(SkImageInfo::Make(width, height, kColorType, kAlphaType),
                pixels, width * sizeof(uint32_t));
    SkPixmap pm_max = max_image.pixmap();
    SkPixmap pm_min = min_image.pixmap();
    for (int y = 0; y < pm.height(); ++y) {
        for (int x = 0; x < pm.width(); ++x) {
            int error = get_error_with_nearby(x, y, pm, pm_max, pm_min) ;
            if (error > 0) {
                badness = SkTMax(error, badness);
                ++badPixelCount;
            }
        }
    }
    int64_t badnessMetric = badness * badPixelCount;
    if (badnessMetric < SK_SKQP_BADNESS_TOLERANCE) {
        std::lock_guard<std::mutex> lock(gMutex);
        gErrors.push_back(Run{SkString(backend), SkString(name), 0, 0});
        if (error_out) {
            *error_out = Error::kNone;
        }
        return 0;
    }
    if (report_directory_path && report_directory_path[0] != '\0') {
        SkString images_directory = SkOSPath::Join(report_directory_path, IMAGES_DIRECTORY_PATH);
        sk_mkdir(images_directory.c_str());

        SkString image_path   = make_path(images_directory, backend, name, PATH_IMG_PNG);
        SkString error_path   = make_path(images_directory, backend, name, PATH_ERR_PNG);
        SkString max_path_out = make_path(images_directory, backend, name, PATH_MAX_PNG);
        SkString min_path_out = make_path(images_directory, backend, name, PATH_MIN_PNG);

        SkAssertResult(WritePixmapToFile(rgba8888_to_pixmap(pixels, width, height),
                                         image_path.c_str()));

        SkBitmap errorBitmap;
        errorBitmap.allocPixels(SkImageInfo::Make(width, height, kColorType, kAlphaType));
        for (int y = 0; y < pm.height(); ++y) {
            for (int x = 0; x < pm.width(); ++x) {
                int error = get_error_with_nearby(x, y, pm, pm_max, pm_min);
                *errorBitmap.getAddr32(x, y) =
                         error > 0 ? 0xFF000000 + (unsigned)error : 0xFFFFFFFF;
            }
        }
        SkAssertResult(WritePixmapToFile(errorBitmap.pixmap(), error_path.c_str()));

        (void)copy(assetManager, max_path.c_str(), max_path_out.c_str());
        (void)copy(assetManager, min_path.c_str(), min_path_out.c_str());

        std::lock_guard<std::mutex> lock(gMutex);
        gErrors.push_back(Run{SkString(backend), SkString(name), badness, badPixelCount});
    }
    if (error_out) {
        *error_out = Error::kNone;
    }
    return (float)badnessMetric;
}

static constexpr char kDocHead[] =
    "<!doctype html>\n"
    "<html lang=\"en\">\n"
    "<head>\n"
    "<meta charset=\"UTF-8\">\n"
    "<title>SkQP Report</title>\n"
    "<style>\n"
    "img { max-width:48%; border:1px green solid;\n"
    "      image-rendering: pixelated;\n"
    "      background-image:url('data:image/png;base64,iVBORw0KGgoA"
    "AAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAAXNSR0IArs4c6QAAAAJiS0dEAP+H"
    "j8y/AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH3gUBEi4DGRAQYgAAAB1J"
    "REFUGNNjfMoAAVJQmokBDdBHgPE/lPFsYN0BABdaAwN6tehMAAAAAElFTkSuQmCC"
    "'); }\n"
    "</style>\n"
    "<script>\n"
    "function ce(t) { return document.createElement(t); }\n"
    "function ct(n) { return document.createTextNode(n); }\n"
    "function ac(u,v) { return u.appendChild(v); }\n"
    "function br(u) { ac(u, ce(\"br\")); }\n"
    "function ma(s, c) { var a = ce(\"a\"); a.href = s; ac(a, c); return a; }\n"
    "function f(backend, gm, e1, e2) {\n"
    "  var b = ce(\"div\");\n"
    "  var x = ce(\"h2\");\n"
    "  var t = backend + \"_\" + gm;\n"
    "  ac(x, ct(t));\n"
    "  ac(b, x);\n"
    "  ac(b, ct(\"backend: \" + backend));\n"
    "  br(b);\n"
    "  ac(b, ct(\"gm name: \" + gm));\n"
    "  br(b);\n"
    "  ac(b, ct(\"maximum error: \" + e1));\n"
    "  br(b);\n"
    "  ac(b, ct(\"bad pixel counts: \" + e2));\n"
    "  br(b);\n"
    "  var q = \"" IMAGES_DIRECTORY_PATH "/\" + backend + \"_\" + gm + \"_\";\n"
    "  var i = ce(\"img\");\n"
    "  i.src = q + \"" PATH_IMG_PNG "\";\n"
    "  i.alt = \"img\";\n"
    "  ac(b, ma(i.src, i));\n"
    "  i = ce(\"img\");\n"
    "  i.src = q + \"" PATH_ERR_PNG "\";\n"
    "  i.alt = \"err\";\n"
    "  ac(b, ma(i.src, i));\n"
    "  br(b);\n"
    "  ac(b, ct(\"Expectation: \"));\n"
    "  ac(b, ma(q + \"" PATH_MAX_PNG "\", ct(\"max\")));\n"
    "  ac(b, ct(\" | \"));\n"
    "  ac(b, ma(q + \"" PATH_MIN_PNG "\", ct(\"min\")));\n"
    "  ac(b, ce(\"hr\"));\n"
    "  b.id = backend + \":\" + gm;\n"
    "  ac(document.body, b);\n"
    "  l = ce(\"li\");\n"
    "  ac(l, ct(\"[\" + e1 + \"] \"));\n"
    "  ac(l, ma(\"#\" + backend +\":\"+ gm , ct(t)));\n"
    "  ac(document.getElementById(\"toc\"), l);\n"
    "}\n"
    "function main() {\n";

static constexpr char kDocMiddle[] =
    "}\n"
    "</script>\n"
    "</head>\n"
    "<body onload=\"main()\">\n"
    "<h1>SkQP Report</h1>\n";

static constexpr char kDocTail[] =
    "<ul id=\"toc\"></ul>\n"
    "<hr>\n"
    "<p>Left image: test result<br>\n"
    "Right image: errors (white = no error, black = smallest error, red = biggest error)</p>\n"
    "<hr>\n"
    "</body>\n"
    "</html>\n";

static void write(SkWStream* wStream, const SkString& text) {
    wStream->write(text.c_str(), text.size());
}

enum class Backend {
    kUnknown,
    kGLES,
    kVulkan,
};

static Backend get_backend(const SkString& s) {
    if (s.equals("gles")) {
        return Backend::kGLES;
    } else if (s.equals("vk")) {
        return Backend::kVulkan;
    }
    return Backend::kUnknown;
}


bool MakeReport(const char* report_directory_path) {
    int glesErrorCount = 0, vkErrorCount = 0, gles = 0, vk = 0;

    SkASSERT_RELEASE(sk_isdir(report_directory_path));
    std::lock_guard<std::mutex> lock(gMutex);
    SkFILEWStream csvOut(SkOSPath::Join(report_directory_path, PATH_CSV).c_str());
    SkFILEWStream htmOut(SkOSPath::Join(report_directory_path, PATH_REPORT).c_str());
    SkASSERT_RELEASE(csvOut.isValid());
    if (!csvOut.isValid() || !htmOut.isValid()) {
        return false;
    }
    htmOut.writeText(kDocHead);
    for (const Run& run : gErrors) {
        auto backend = get_backend(run.fBackend);
        switch (backend) {
            case Backend::kGLES: ++gles; break;
            case Backend::kVulkan: ++vk; break;
            default: break;
        }
        write(&csvOut, SkStringPrintf("\"%s\",\"%s\",%d,%d\n",
                                      run.fBackend.c_str(), run.fGM.c_str(),
                                      run.fMaxerror, run.fBadpixels));
        if (run.fMaxerror == 0 && run.fBadpixels == 0) {
            continue;
        }
        write(&htmOut, SkStringPrintf("  f(\"%s\", \"%s\", %d, %d);\n",
                                      run.fBackend.c_str(), run.fGM.c_str(),
                                      run.fMaxerror, run.fBadpixels));
        switch (backend) {
            case Backend::kGLES: ++glesErrorCount; break;
            case Backend::kVulkan: ++vkErrorCount; break;
            default: break;
        }
    }
    htmOut.writeText(kDocMiddle);
    write(&htmOut, SkStringPrintf("<p>gles errors: %d (of %d)</br>\n"
                                  "vk errors: %d (of %d)</p>\n",
                                  glesErrorCount, gles, vkErrorCount, vk));
    htmOut.writeText(kDocTail);
    return true;
}
}  // namespace gmkb
