/*
 * 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


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

// TODO(halcanary) SkQP version 2 (for Q-release) should have a much cleaner mechanism.
static bool good_enough(const char* name, int64_t badnessMetric) {
    static const struct {
        const char* name;
        int64_t tolerance;
    } allowedBadnesses[] = {
        // These values are rounded up from failing tests reported by vendor.
        { "blurroundrect-WH-100x100-unevenCorners", 360   },
        { "circular_arcs_stroke_and_fill_round",    110   },
        { "circular_arcs_weird",                    13000 },
        { "complexclip2_path_aa",                   570   },
        { "complexclip2_rrect_aa",                  150  },
        { "drawTextRSXform",                        1100  },
        { "drrect",                                 410   },
        { "gradients_2pt_conical_inside_repeat",    340  },
        { "patheffect",                             260   },
        { "simpleshapes",                           200   },
        { "skbug1719",                              920   },
        { "strokes_poly",                           1100  },
        { "stroketext",                             700   },
    };
    for (auto allowedBadness : allowedBadnesses) {
        if (0 == strcmp(allowedBadness.name, name)) {
            return badnessMetric < allowedBadness.tolerance;
        }
    }
    return badnessMetric < SK_SKQP_BADNESS_TOLERANCE;
}

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 (good_enough(name, badnessMetric)) {
        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
