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

#include "include/core/SkPoint.h"
#include "src/core/SkRandom.h"
#include "src/gpu/graphite/sparse_strips/MSAA_LUT.h"
#include "tests/Test.h"

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstring>

namespace skgpu::graphite {

namespace {

uint8_t compute_naive_mask(SkPoint p0, SkPoint p1) {
    float dx = p1.fX - p0.fX;
    float dy = p1.fY - p0.fY;
    if (std::abs(dx) < 1e-9f && std::abs(dy) < 1e-9f) return 0;
    float nx = dy;
    float ny = -dx;
    float len = std::hypot(nx, ny);
    nx /= len;
    ny /= len;

    if (nx < 0.0f) {
        nx = -nx;
        ny = -ny;
    }
    float c = nx * p0.fX + ny * p0.fY;

    SparseStripConfig::SubSampleType mask = 0;
    for (int i = 0; i < SparseStripConfig::kNumSubSamples; ++i) {
        float sx = (kMsaaPattern<SparseStripConfig::SubSampleType>[i] + 0.5f) /
                   static_cast<float>(SparseStripConfig::kNumSubSamples);
        float sy = (i + 0.5f) / static_cast<float>(SparseStripConfig::kNumSubSamples);
        if (nx * sx + ny * sy - c > 0.0f) {
            mask |= (1 << i);
        }
    }
    return mask;
}

SparseStripConfig::SubSampleType lookup_LUT(SkPoint p0, SkPoint p1,
                                            const SparseStripConfig::LUTArray& lut) {
    float dx = p1.fX - p0.fX;
    float dy = p1.fY - p0.fY;

    if (std::abs(dx) < 1e-9f && std::abs(dy) < 1e-9f) {
        return 0;
    }

    float nx = dy;
    float ny = -dx;

    // Match the Naive compute's normal orientation
    if (nx < 0.0f) {
        nx = -nx;
        ny = -ny;
    }
    float c = nx * p0.fX + ny * p0.fY;

    bool isPos = ny <= 0.0f;
    float D = nx + std::abs(ny);

    // Squash the slope
    float s = std::abs(ny) / D;
    float t = ((isPos ? nx : D) - c) / D;

    static constexpr int kWidth = SparseStripConfig::kLUTMaskWidth;
    static constexpr int kHeight = SparseStripConfig::kLUTMaskHeight;
    static constexpr int halfHeight = kHeight / 2;

    int u = std::clamp(static_cast<int>(std::floor(t * kWidth)), 0, kWidth - 1);
    int v_mod = std::clamp(static_cast<int>(std::floor(s * halfHeight)), 0, halfHeight - 1);
    int v = isPos ? (v_mod + halfHeight) : v_mod;

    return lut[v * kWidth + u];
}

// Note: Although it is possible for a line segment to end within a pixel, we do not test that case
// here. The LUT's quantization relies solely on a parameterized slope and intercept, effectively
// treating the segment as an infinite line that crosses the entire pixel. Downstream subsample
// masking logic independently handles the specific case of endpoints falling inside a pixel.
static SkPoint pick_random_square_point(SkRandom* rand) {
    int edge = rand->nextU() % 4;
    float t = rand->nextF();
    switch (edge) {
        case 0:
            return {t, 0.0f};
        case 1:
            return {1.0f, t};
        case 2:
            return {t, 1.0f};
        default:
            return {0.0f, t};
    }
}

template <typename LookupFunc>
void test_LUT(skiatest::Reporter* reporter,
             const char* lutName,
             const SparseStripConfig::LUTArray& lut,
             uint32_t seed,
             LookupFunc lookupFunc) {
    SkRandom rand(seed);

    constexpr int kIterations = 10000;

    // Track and report the number of 1,2, and 3 sample errors. These are not reported as errors as
    // some noise is expected due to quantization to the LUT.
    constexpr uint32_t kErrorLimit = 3;
    std::array<uint32_t, kErrorLimit> minorErrorCount = {0, 0, 0};

    for (int i = 0; i < kIterations; ++i) {
        SkPoint p0 = pick_random_square_point(&rand);
        SkPoint p1 = pick_random_square_point(&rand);

        uint8_t expected = compute_naive_mask(p0, p1);
        uint8_t actual = lookupFunc(p0, p1, lut);

        uint8_t diff = expected ^ actual;
        uint32_t bitErrors = std::popcount(diff);

        if (bitErrors > kErrorLimit) {
            uint32_t hexP0X, hexP0Y, hexP1X, hexP1Y;
            std::memcpy(&hexP0X, &p0.fX, 4);
            std::memcpy(&hexP0Y, &p0.fY, 4);
            std::memcpy(&hexP1X, &p1.fX, 4);
            std::memcpy(&hexP1Y, &p1.fY, 4);
            ERRORF(reporter,
                    "[%s] CRITICAL Fail at iter %d (Seed: %u). Expected 0x%02x, "
                    "Got 0x%02x (%u bits diff)\n"
                    "P0: %f, %f (0x%08x, 0x%08x)\n"
                    "P1: %f, %f (0x%08x, 0x%08x)",
                    lutName, i, seed, expected, actual, bitErrors,
                    p0.fX, p0.fY, hexP0X, hexP0Y, p1.fX, p1.fY, hexP1X, hexP1Y);
        } else if (bitErrors > 0) {
            minorErrorCount[bitErrors - 1]++;
        }
    }

    INFOF(reporter,
          "[%s] Minor Error Summary (Seed: %u): 1-bit: %u, 2-bit: %u, 3-bit: %u",
          lutName,
          seed,
          minorErrorCount[0],
          minorErrorCount[1],
          minorErrorCount[2]);
}

}  // namespace

DEF_TEST(SparseStrips_LUTTest, reporter) {
    auto now = std::chrono::high_resolution_clock::now();
    uint32_t seed = static_cast<uint32_t>(now.time_since_epoch().count());

    const SparseStripConfig::LUTArray msaaLUT = GenerateMSAALUT();
    test_LUT(reporter, "SlopeBasedLUT", msaaLUT, seed, lookup_LUT);
}

}  // namespace skgpu::graphite
