#include "sensorutils.hpp"

#include <cmath>

#include "gtest/gtest.h"

// There is a surprising amount of slop in the math,
// thanks to all the rounding and conversion.
// The "x" byte value can drift by up to 2 away, I have seen.
static constexpr int8_t expectedSlopX = 2;

// Unlike expectedSlopX, this is a ratio, not an integer
// It scales based on the range of "y"
static constexpr double expectedSlopY = 0.01;

// The algorithm here was copied from ipmitool
// sdr_convert_sensor_reading() function
// https://github.com/ipmitool/ipmitool/blob/42a023ff0726c80e8cc7d30315b987fe568a981d/lib/ipmi_sdr.c#L360
double ipmitool_y_from_x(uint8_t x, int m, int k2_rExp, int b, int k1_bExp,
                         bool bSigned)
{
    double result;

    // Rename to exactly match names and types (except analog) from ipmitool
    uint8_t val = x;
    double k1 = k1_bExp;
    double k2 = k2_rExp;
    int analog = bSigned ? 2 : 0;

    // Begin paste here
    // Only change is to comment out complicated structure in switch statement

    switch (/*sensor->cmn.unit.*/ analog)
    {
        case 0:
            result = (double)(((m * val) + (b * pow(10, k1))) * pow(10, k2));
            break;
        case 1:
            if (val & 0x80)
                val++;
            /* Deliberately fall through to case 2. */
            [[fallthrough]];
        case 2:
            result =
                (double)(((m * (int8_t)val) + (b * pow(10, k1))) * pow(10, k2));
            break;
        default:
            /* Oops! This isn't an analog sensor. */
            return 0.0;
    }

    // End paste here
    // Ignoring linearization curves and postprocessing that follows,
    // assuming all sensors are perfectly linear
    return result;
}

void testValue(int x, double y, int16_t M, int8_t rExp, int16_t B, int8_t bExp,
               bool bSigned, double yRange)
{
    double yRoundtrip;
    int result;

    // There is intentionally no exception catching here,
    // because if getSensorAttributes() returned true,
    // it is a promise that all of these should work.
    if (bSigned)
    {
        int8_t expect = x;
        int8_t actual = ipmi::scaleIPMIValueFromDouble(y, M, rExp, B, bExp,
                                                       bSigned);

        result = actual;
        yRoundtrip = ipmitool_y_from_x(actual, M, rExp, B, bExp, bSigned);

        EXPECT_NEAR(actual, expect, expectedSlopX);
    }
    else
    {
        uint8_t expect = x;
        uint8_t actual = ipmi::scaleIPMIValueFromDouble(y, M, rExp, B, bExp,
                                                        bSigned);

        result = actual;
        yRoundtrip = ipmitool_y_from_x(actual, M, rExp, B, bExp, bSigned);

        EXPECT_NEAR(actual, expect, expectedSlopX);
    }

    // Scale the amount of allowed slop in y based on range, so ratio similar
    double yTolerance = yRange * expectedSlopY;

    EXPECT_NEAR(y, yRoundtrip, yTolerance);

    char szFormat[1024];
    sprintf(szFormat,
            "Value | xExpect %4d | xResult %4d "
            "| M %5d | rExp %3d "
            "| B %5d | bExp %3d | bSigned %1d | y %18.3f | yRoundtrip %18.3f\n",
            x, result, M, (int)rExp, B, (int)bExp, (int)bSigned, y, yRoundtrip);
    std::cout << szFormat;
}

void testBounds(double yMin, double yMax, bool bExpectedOutcome = true)
{
    int16_t mValue;
    int8_t rExp;
    int16_t bValue;
    int8_t bExp;
    bool bSigned;
    bool result;

    result = ipmi::getSensorAttributes(yMax, yMin, mValue, rExp, bValue, bExp,
                                       bSigned);
    EXPECT_EQ(result, bExpectedOutcome);

    if (!result)
    {
        return;
    }

    char szFormat[1024];
    sprintf(szFormat,
            "Bounds | yMin %18.3f | yMax %18.3f | M %5d"
            " | rExp %3d | B %5d | bExp %3d | bSigned %1d\n",
            yMin, yMax, mValue, (int)rExp, bValue, (int)bExp, (int)bSigned);
    std::cout << szFormat;

    double y50p = (yMin + yMax) / 2.0;

    // Average the average
    double y25p = (yMin + y50p) / 2.0;
    double y75p = (y50p + yMax) / 2.0;

    // This range value is only used for tolerance checking, not computation
    double yRange = yMax - yMin;

    if (bSigned)
    {
        int8_t xMin = -128;
        int8_t x25p = -64;
        int8_t x50p = 0;
        int8_t x75p = 64;
        int8_t xMax = 127;

        testValue(xMin, yMin, mValue, rExp, bValue, bExp, bSigned, yRange);
        testValue(x25p, y25p, mValue, rExp, bValue, bExp, bSigned, yRange);
        testValue(x50p, y50p, mValue, rExp, bValue, bExp, bSigned, yRange);
        testValue(x75p, y75p, mValue, rExp, bValue, bExp, bSigned, yRange);
        testValue(xMax, yMax, mValue, rExp, bValue, bExp, bSigned, yRange);
    }
    else
    {
        uint8_t xMin = 0;
        uint8_t x25p = 64;
        uint8_t x50p = 128;
        uint8_t x75p = 192;
        uint8_t xMax = 255;

        testValue(xMin, yMin, mValue, rExp, bValue, bExp, bSigned, yRange);
        testValue(x25p, y25p, mValue, rExp, bValue, bExp, bSigned, yRange);
        testValue(x50p, y50p, mValue, rExp, bValue, bExp, bSigned, yRange);
        testValue(x75p, y75p, mValue, rExp, bValue, bExp, bSigned, yRange);
        testValue(xMax, yMax, mValue, rExp, bValue, bExp, bSigned, yRange);
    }
}

void testRanges(void)
{
    // The ranges from the main TEST function
    testBounds(0x0, 0xFF);
    testBounds(-128, 127);
    testBounds(0, 16000);
    testBounds(0, 20);
    testBounds(8000, 16000);
    testBounds(-10, 10);
    testBounds(0, 277);
    testBounds(0, 0, false);
    testBounds(10, 12);

    // Additional test cases recommended to me by hardware people
    testBounds(-40, 150);
    testBounds(0, 1);
    testBounds(0, 2);
    testBounds(0, 4);
    testBounds(0, 8);
    testBounds(35, 65);
    testBounds(0, 18);
    testBounds(0, 25);
    testBounds(0, 80);
    testBounds(0, 500);

    // Additional sanity checks
    testBounds(0, 255);
    testBounds(-255, 0);
    testBounds(-255, 255);
    testBounds(0, 1000);
    testBounds(-1000, 0);
    testBounds(-1000, 1000);
    testBounds(0, 255000);
    testBounds(-128000000, 127000000);
    testBounds(-50000, 0);
    testBounds(-40000, 10000);
    testBounds(-30000, 20000);
    testBounds(-20000, 30000);
    testBounds(-10000, 40000);
    testBounds(0, 50000);
    testBounds(-1e3, 1e6);
    testBounds(-1e6, 1e3);

    // Extreme ranges are now possible
    testBounds(0, 1e10);
    testBounds(0, 1e11);
    testBounds(0, 1e12);
    testBounds(0, 1e13, false);
    testBounds(-1e10, 0);
    testBounds(-1e11, 0);
    testBounds(-1e12, 0);
    testBounds(-1e13, 0, false);
    testBounds(-1e9, 1e9);
    testBounds(-1e10, 1e10);
    testBounds(-1e11, 1e11);
    testBounds(-1e12, 1e12, false);

    // Large multiplier but small offset
    testBounds(1e4, 1e4 + 255);
    testBounds(1e5, 1e5 + 255);
    testBounds(1e6, 1e6 + 255);
    testBounds(1e7, 1e7 + 255);
    testBounds(1e8, 1e8 + 255);
    testBounds(1e9, 1e9 + 255);
    testBounds(1e10, 1e10 + 255, false);

    // Input validation against garbage
    testBounds(0, INFINITY, false);
    testBounds(-INFINITY, 0, false);
    testBounds(-INFINITY, INFINITY, false);
    testBounds(0, NAN, false);
    testBounds(NAN, 0, false);
    testBounds(NAN, NAN, false);

    // Noteworthy binary integers
    testBounds(0, std::pow(2.0, 32.0) - 1.0);
    testBounds(0, std::pow(2.0, 32.0));
    testBounds(0.0 - std::pow(2.0, 31.0), std::pow(2.0, 31.0));
    testBounds((0.0 - std::pow(2.0, 31.0)) - 1.0, std::pow(2.0, 31.0));

    // Similar but negative (note additional commented-out below)
    testBounds(-1e1, (-1e1) + 255);
    testBounds(-1e2, (-1e2) + 255);

    // Ranges of negative numbers (note additional commented-out below)
    testBounds(-10400, -10000);
    testBounds(-15000, -14000);
    testBounds(-10000, -9000);
    testBounds(-1000, -900);
    testBounds(-1000, -800);
    testBounds(-1000, -700);
    testBounds(-1000, -740);

    // Very small ranges (note additional commented-out below)
    testBounds(0, 0.1);
    testBounds(0, 0.01);
    testBounds(0, 0.001);
    testBounds(0, 0.0001);
    testBounds(0, 0.000001, false);

#if 0
    // TODO(): The algorithm in this module is better than it was before,
    // but the resulting value of X is still wrong under certain conditions,
    // such as when the range between min and max is around 255,
    // and the offset is fairly extreme compared to the multiplier.
    // Not sure why this is, but these ranges are contrived,
    // and real-world examples would most likely never be this way.
    testBounds(-10290, -10000);
    testBounds(-10280, -10000);
    testBounds(-10275,-10000);
    testBounds(-10270,-10000);
    testBounds(-10265,-10000);
    testBounds(-10260,-10000);
    testBounds(-10255,-10000);
    testBounds(-10250,-10000);
    testBounds(-10245,-10000);
    testBounds(-10256,-10000);
    testBounds(-10512, -10000);
    testBounds(-11024, -10000);

    // TODO(): This also fails, due to extreme small range, loss of precision
    testBounds(0, 0.00001);

    // TODO(): Interestingly, if bSigned is forced false,
    // causing "x" to have range of (0,255) instead of (-128,127),
    // these test cases change from failing to passing!
    // Not sure why this is, perhaps a mathematician might know.
    testBounds(-10300, -10000);
    testBounds(-1000,-750);
    testBounds(-1e3, (-1e3) + 255);
    testBounds(-1e4, (-1e4) + 255);
    testBounds(-1e5, (-1e5) + 255);
    testBounds(-1e6, (-1e6) + 255);
#endif
}

TEST(sensorutils, TranslateToIPMI)
{
    /*bool getSensorAttributes(double maxValue, double minValue, int16_t
       &mValue, int8_t &rExp, int16_t &bValue, int8_t &bExp, bool &bSigned); */
    // normal unsigned sensor
    double maxValue = 0xFF;
    double minValue = 0x0;
    int16_t mValue;
    int8_t rExp;
    int16_t bValue;
    int8_t bExp;
    bool bSigned;
    bool result;

    uint8_t scaledVal;

    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
                                       bExp, bSigned);
    EXPECT_EQ(result, true);
    if (result)
    {
        EXPECT_EQ(bSigned, false);
        EXPECT_EQ(mValue, 1);
        EXPECT_EQ(rExp, 0);
        EXPECT_EQ(bValue, 0);
        EXPECT_EQ(bExp, 0);
    }
    double expected = 0x50;
    scaledVal = ipmi::scaleIPMIValueFromDouble(0x50, mValue, rExp, bValue, bExp,
                                               bSigned);
    EXPECT_NEAR(scaledVal, expected, expected * 0.01);

    // normal signed sensor
    maxValue = 127;
    minValue = -128;

    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
                                       bExp, bSigned);
    EXPECT_EQ(result, true);

    if (result)
    {
        EXPECT_EQ(bSigned, true);
        EXPECT_EQ(mValue, 1);
        EXPECT_EQ(rExp, 0);
        EXPECT_EQ(bValue, 0);
        EXPECT_EQ(bExp, 0);
    }

    // check negative values
    expected = 236; // 2s compliment -20
    scaledVal = ipmi::scaleIPMIValueFromDouble(-20, mValue, rExp, bValue, bExp,
                                               bSigned);
    EXPECT_NEAR(scaledVal, expected, expected * 0.01);

    // fan example
    maxValue = 16000;
    minValue = 0;

    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
                                       bExp, bSigned);
    EXPECT_EQ(result, true);
    if (result)
    {
        EXPECT_EQ(bSigned, false);
        EXPECT_EQ(mValue, floor((16000.0 / 0xFF) + 0.5));
        EXPECT_EQ(rExp, 0);
        EXPECT_EQ(bValue, 0);
        EXPECT_EQ(bExp, 0);
    }

    // voltage sensor example
    maxValue = 20;
    minValue = 0;

    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
                                       bExp, bSigned);
    EXPECT_EQ(result, true);
    if (result)
    {
        EXPECT_EQ(bSigned, false);
        EXPECT_EQ(mValue, floor(((20.0 / 0xFF) / std::pow(10, rExp)) + 0.5));
        EXPECT_EQ(rExp, -3);
        EXPECT_EQ(bValue, 0);
        EXPECT_EQ(bExp, 0);
    }
    scaledVal = ipmi::scaleIPMIValueFromDouble(12.2, mValue, rExp, bValue, bExp,
                                               bSigned);

    expected = 12.2 / (mValue * std::pow(10, rExp));
    EXPECT_NEAR(scaledVal, expected, expected * 0.01);

    // shifted fan example
    maxValue = 16000;
    minValue = 8000;

    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
                                       bExp, bSigned);
    EXPECT_EQ(result, true);

    if (result)
    {
        EXPECT_EQ(bSigned, false);
        EXPECT_EQ(mValue, floor(((8000.0 / 0xFF) / std::pow(10, rExp)) + 0.5));
        EXPECT_EQ(rExp, -1);
        EXPECT_EQ(bValue, 8);
        EXPECT_EQ(bExp, 4);
    }

    // signed voltage sensor example
    maxValue = 10;
    minValue = -10;

    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
                                       bExp, bSigned);
    EXPECT_EQ(result, true);
    if (result)
    {
        EXPECT_EQ(bSigned, true);
        EXPECT_EQ(mValue, floor(((20.0 / 0xFF) / std::pow(10, rExp)) + 0.5));
        EXPECT_EQ(rExp, -3);
        // Although this seems like a weird magic number,
        // it is because the range (-128,127) is not symmetrical about zero,
        // unlike the range (-10,10), so this introduces some distortion.
        EXPECT_EQ(bValue, 392);
        EXPECT_EQ(bExp, -1);
    }

    scaledVal = ipmi::scaleIPMIValueFromDouble(5, mValue, rExp, bValue, bExp,
                                               bSigned);

    expected = 5 / (mValue * std::pow(10, rExp));
    EXPECT_NEAR(scaledVal, expected, expected * 0.01);

    // reading = max example
    maxValue = 277;
    minValue = 0;

    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
                                       bExp, bSigned);
    EXPECT_EQ(result, true);
    if (result)
    {
        EXPECT_EQ(bSigned, false);
    }

    scaledVal = ipmi::scaleIPMIValueFromDouble(maxValue, mValue, rExp, bValue,
                                               bExp, bSigned);

    expected = 0xFF;
    EXPECT_NEAR(scaledVal, expected, expected * 0.01);

    // 0, 0 failure
    maxValue = 0;
    minValue = 0;
    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
                                       bExp, bSigned);
    EXPECT_EQ(result, false);

    // too close *success* (was previously failure!)
    maxValue = 12;
    minValue = 10;
    result = ipmi::getSensorAttributes(maxValue, minValue, mValue, rExp, bValue,
                                       bExp, bSigned);
    EXPECT_EQ(result, true);
    if (result)
    {
        EXPECT_EQ(bSigned, false);
        EXPECT_EQ(mValue, floor(((2.0 / 0xFF) / std::pow(10, rExp)) + 0.5));
        EXPECT_EQ(rExp, -4);
        EXPECT_EQ(bValue, 1);
        EXPECT_EQ(bExp, 5);
    }
}

TEST(sensorUtils, TestRanges)
{
    // Additional test ranges, each running through a series of values,
    // to make sure the values of "x" and "y" go together and make sense,
    // for the resulting scaling attributes from each range.
    // Unlike the TranslateToIPMI test, exact matches of the
    // getSensorAttributes() results (the coefficients) are not required,
    // because they are tested through actual use, relating "x" to "y".
    testRanges();
}
