// © 2020 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include <cmath>
#include <iostream>

#include "charstr.h"
#include "cmemory.h"
#include "filestrm.h"
#include "intltest.h"
#include "number_decimalquantity.h"
#include "putilimp.h"
#include "unicode/ctest.h"
#include "unicode/measunit.h"
#include "unicode/measure.h"
#include "unicode/unistr.h"
#include "unicode/unum.h"
#include "unicode/ures.h"
#include "units_complexconverter.h"
#include "units_converter.h"
#include "units_data.h"
#include "units_router.h"
#include "uparse.h"
#include "uresimp.h"

struct UnitConversionTestCase {
    const StringPiece source;
    const StringPiece target;
    const double inputValue;
    const double expectedValue;
};

using ::icu::number::impl::DecimalQuantity;
using namespace ::icu::units;

class UnitsTest : public IntlTest {
  public:
    UnitsTest() {}

    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = NULL);

    void testUnitConstantFreshness();
    void testExtractConvertibility();
    void testConverterWithCLDRTests();
    void testComplexUnitsConverter();
    void testComplexUnitsConverterSorting();
    void testUnitPreferencesWithCLDRTests();
    void testConverter();
};

extern IntlTest *createUnitsTest() { return new UnitsTest(); }

void UnitsTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) {
    if (exec) {
        logln("TestSuite UnitsTest: ");
    }
    TESTCASE_AUTO_BEGIN;
    TESTCASE_AUTO(testUnitConstantFreshness);
    TESTCASE_AUTO(testExtractConvertibility);
    TESTCASE_AUTO(testConverterWithCLDRTests);
    TESTCASE_AUTO(testComplexUnitsConverter);
    TESTCASE_AUTO(testComplexUnitsConverterSorting);
    TESTCASE_AUTO(testUnitPreferencesWithCLDRTests);
    TESTCASE_AUTO(testConverter);
    TESTCASE_AUTO_END;
}

// Tests the hard-coded constants in the code against constants that appear in
// units.txt.
void UnitsTest::testUnitConstantFreshness() {
    IcuTestErrorCode status(*this, "testUnitConstantFreshness");
    LocalUResourceBundlePointer unitsBundle(ures_openDirect(NULL, "units", status));
    LocalUResourceBundlePointer unitConstants(
        ures_getByKey(unitsBundle.getAlias(), "unitConstants", NULL, status));

    while (ures_hasNext(unitConstants.getAlias())) {
        int32_t len;
        const char *constant = NULL;
        ures_getNextString(unitConstants.getAlias(), &len, &constant, status);

        Factor factor;
        addSingleFactorConstant(constant, 1, POSITIVE, factor, status);
        if (status.errDataIfFailureAndReset(
                "addSingleFactorConstant(<%s>, ...).\n\n"
                "If U_INVALID_FORMAT_ERROR, please check that \"icu4c/source/i18n/units_converter.cpp\" "
                "has all constants? Is \"%s\" a new constant?\n"
                "See docs/processes/release/tasks/updating-measure-unit.md for more information.\n",
                constant, constant)) {
            continue;
        }

        // Check the values of constants that have a simple numeric value
        factor.substituteConstants();
        int32_t uLen;
        UnicodeString uVal = ures_getStringByKey(unitConstants.getAlias(), constant, &uLen, status);
        CharString val;
        val.appendInvariantChars(uVal, status);
        if (status.errDataIfFailureAndReset("Failed to get constant value for %s.", constant)) {
            continue;
        }
        DecimalQuantity dqVal;
        UErrorCode parseStatus = U_ZERO_ERROR;
        // TODO(units): unify with strToDouble() in units_converter.cpp
        dqVal.setToDecNumber(val.toStringPiece(), parseStatus);
        if (!U_SUCCESS(parseStatus)) {
            // Not simple to parse, skip validating this constant's value. (We
            // leave catching mistakes to the data-driven integration tests.)
            continue;
        }
        double expectedNumerator = dqVal.toDouble();
        assertEquals(UnicodeString("Constant ") + constant + u" numerator", expectedNumerator,
                     factor.factorNum);
        assertEquals(UnicodeString("Constant ") + constant + u" denominator", 1.0, factor.factorDen);
    }
}

void UnitsTest::testExtractConvertibility() {
    IcuTestErrorCode status(*this, "UnitsTest::testExtractConvertibility");

    struct TestCase {
        const char *const source;
        const char *const target;
        const Convertibility expectedState;
    } testCases[]{
        {"meter", "foot", CONVERTIBLE},                                              //
        {"kilometer", "foot", CONVERTIBLE},                                          //
        {"hectare", "square-foot", CONVERTIBLE},                                     //
        {"kilometer-per-second", "second-per-meter", RECIPROCAL},                    //
        {"square-meter", "square-foot", CONVERTIBLE},                                //
        {"kilometer-per-second", "foot-per-second", CONVERTIBLE},                    //
        {"square-hectare", "pow4-foot", CONVERTIBLE},                                //
        {"square-kilometer-per-second", "second-per-square-meter", RECIPROCAL},      //
        {"cubic-kilometer-per-second-meter", "second-per-square-meter", RECIPROCAL}, //
        {"square-meter-per-square-hour", "hectare-per-square-second", CONVERTIBLE},  //
        {"hertz", "revolution-per-second", CONVERTIBLE},                             //
        {"millimeter", "meter", CONVERTIBLE},                                        //
        {"yard", "meter", CONVERTIBLE},                                              //
        {"ounce-troy", "kilogram", CONVERTIBLE},                                     //
        {"percent", "portion", CONVERTIBLE},                                         //
        {"ofhg", "kilogram-per-square-meter-square-second", CONVERTIBLE},            //
        {"second-per-meter", "meter-per-second", RECIPROCAL},                        //
    };

    for (const auto &testCase : testCases) {
        MeasureUnitImpl source = MeasureUnitImpl::forIdentifier(testCase.source, status);
        if (status.errIfFailureAndReset("source MeasureUnitImpl::forIdentifier(\"%s\", ...)",
                                        testCase.source)) {
            continue;
        }
        MeasureUnitImpl target = MeasureUnitImpl::forIdentifier(testCase.target, status);
        if (status.errIfFailureAndReset("target MeasureUnitImpl::forIdentifier(\"%s\", ...)",
                                        testCase.target)) {
            continue;
        }

        ConversionRates conversionRates(status);
        if (status.errIfFailureAndReset("conversionRates(status)")) {
            continue;
        }
        auto convertibility = extractConvertibility(source, target, conversionRates, status);
        if (status.errIfFailureAndReset("extractConvertibility(<%s>, <%s>, ...)", testCase.source,
                                        testCase.target)) {
            continue;
        }

        assertEquals(UnicodeString("Conversion Capability: ") + testCase.source + " to " +
                         testCase.target,
                     testCase.expectedState, convertibility);
    }
}

void UnitsTest::testConverter() {
    IcuTestErrorCode status(*this, "UnitsTest::testConverter");

    // Test Cases
    struct TestCase {
        const char *source;
        const char *target;
        const double inputValue;
        const double expectedValue;
    } testCases[]{
        // SI Prefixes
        {"gram", "kilogram", 1.0, 0.001},
        {"milligram", "kilogram", 1.0, 0.000001},
        {"microgram", "kilogram", 1.0, 0.000000001},
        {"megagram", "gram", 1.0, 1000000},
        {"megagram", "kilogram", 1.0, 1000},
        {"gigabyte", "byte", 1.0, 1000000000},
        {"megawatt", "watt", 1.0, 1000000},
        {"megawatt", "kilowatt", 1.0, 1000},
        // Binary Prefixes
        {"kilobyte", "byte", 1, 1000},
        {"kibibyte", "byte", 1, 1024},
        {"mebibyte", "byte", 1, 1048576},
        {"gibibyte", "kibibyte", 1, 1048576},
        {"pebibyte", "tebibyte", 4, 4096},
        {"zebibyte", "pebibyte", 1.0/16, 65536.0},
        {"yobibyte", "exbibyte", 1, 1048576},
        // Mass
        {"gram", "kilogram", 1.0, 0.001},
        {"pound", "kilogram", 1.0, 0.453592},
        {"pound", "kilogram", 2.0, 0.907185},
        {"ounce", "pound", 16.0, 1.0},
        {"ounce", "kilogram", 16.0, 0.453592},
        {"ton", "pound", 1.0, 2000},
        {"stone", "pound", 1.0, 14},
        {"stone", "kilogram", 1.0, 6.35029},
        // Temperature
        {"celsius", "fahrenheit", 0.0, 32.0},
        {"celsius", "fahrenheit", 10.0, 50.0},
        {"celsius", "fahrenheit", 1000, 1832},
        {"fahrenheit", "celsius", 32.0, 0.0},
        {"fahrenheit", "celsius", 89.6, 32},
        {"fahrenheit", "fahrenheit", 1000, 1000},
        {"kelvin", "fahrenheit", 0.0, -459.67},
        {"kelvin", "fahrenheit", 300, 80.33},
        {"kelvin", "celsius", 0.0, -273.15},
        {"kelvin", "celsius", 300.0, 26.85},
        // Area
        {"square-meter", "square-yard", 10.0, 11.9599},
        {"hectare", "square-yard", 1.0, 11959.9},
        {"square-mile", "square-foot", 0.0001, 2787.84},
        {"hectare", "square-yard", 1.0, 11959.9},
        {"hectare", "square-meter", 1.0, 10000},
        {"hectare", "square-meter", 0.0, 0.0},
        {"square-mile", "square-foot", 0.0001, 2787.84},
        {"square-yard", "square-foot", 10, 90},
        {"square-yard", "square-foot", 0, 0},
        {"square-yard", "square-foot", 0.000001, 0.000009},
        {"square-mile", "square-foot", 0.0, 0.0},
    };

    for (const auto &testCase : testCases) {
        MeasureUnitImpl source = MeasureUnitImpl::forIdentifier(testCase.source, status);
        if (status.errIfFailureAndReset("source MeasureUnitImpl::forIdentifier(\"%s\", ...)",
                                        testCase.source)) {
            continue;
        }
        MeasureUnitImpl target = MeasureUnitImpl::forIdentifier(testCase.target, status);
        if (status.errIfFailureAndReset("target MeasureUnitImpl::forIdentifier(\"%s\", ...)",
                                        testCase.target)) {
            continue;
        }

        ConversionRates conversionRates(status);
        if (status.errIfFailureAndReset("conversionRates(status)")) {
            continue;
        }
        UnitsConverter converter(source, target, conversionRates, status);
        if (status.errIfFailureAndReset("UnitsConverter(<%s>, <%s>, ...)", testCase.source,
                                        testCase.target)) {
            continue;
        }

        double maxDelta = 1e-6 * uprv_fabs(testCase.expectedValue);
        if (testCase.expectedValue == 0) {
            maxDelta = 1e-12;
        }
        assertEqualsNear(UnicodeString("testConverter: ") + testCase.source + " to " + testCase.target,
                         testCase.expectedValue, converter.convert(testCase.inputValue), maxDelta);
    }
}

/**
 * Trims whitespace off of the specified string.
 * @param field is two pointers pointing at the start and end of the string.
 * @return A StringPiece with initial and final space characters trimmed off.
 */
StringPiece trimField(char *(&field)[2]) {
    const char *start = field[0];
    start = u_skipWhitespace(start);
    if (start >= field[1]) {
        start = field[1];
    }
    const char *end = field[1];
    while ((start < end) && U_IS_INV_WHITESPACE(*(end - 1))) {
        end--;
    }
    int32_t length = (int32_t)(end - start);
    return StringPiece(start, length);
}

// Used for passing context to unitsTestDataLineFn via u_parseDelimitedFile.
struct UnitsTestContext {
    // Provides access to UnitsTest methods like logln.
    UnitsTest *unitsTest;
    // Conversion rates: does not take ownership.
    ConversionRates *conversionRates;
};

/**
 * Deals with a single data-driven unit test for unit conversions.
 *
 * This is a UParseLineFn as required by u_parseDelimitedFile, intended for
 * parsing unitsTest.txt.
 *
 * @param context Must point at a UnitsTestContext struct.
 * @param fields A list of pointer-pairs, each pair pointing at the start and
 * end of each field. End pointers are important because these are *not*
 * null-terminated strings. (Interpreted as a null-terminated string,
 * fields[0][0] points at the whole line.)
 * @param fieldCount The number of fields (pointer pairs) passed to the fields
 * parameter.
 * @param pErrorCode Receives status.
 */
void unitsTestDataLineFn(void *context, char *fields[][2], int32_t fieldCount, UErrorCode *pErrorCode) {
    if (U_FAILURE(*pErrorCode)) {
        return;
    }
    UnitsTestContext *ctx = (UnitsTestContext *)context;
    UnitsTest *unitsTest = ctx->unitsTest;
    (void)fieldCount; // unused UParseLineFn variable
    IcuTestErrorCode status(*unitsTest, "unitsTestDatalineFn");

    StringPiece quantity = trimField(fields[0]);
    StringPiece x = trimField(fields[1]);
    StringPiece y = trimField(fields[2]);
    StringPiece commentConversionFormula = trimField(fields[3]);
    StringPiece utf8Expected = trimField(fields[4]);

    UNumberFormat *nf = unum_open(UNUM_DEFAULT, NULL, -1, "en_US", NULL, status);
    if (status.errIfFailureAndReset("unum_open failed")) {
        return;
    }
    UnicodeString uExpected = UnicodeString::fromUTF8(utf8Expected);
    double expected = unum_parseDouble(nf, uExpected.getBuffer(), uExpected.length(), 0, status);
    unum_close(nf);
    if (status.errIfFailureAndReset("unum_parseDouble(\"%s\") failed", utf8Expected)) {
        return;
    }

    CharString sourceIdent(x, status);
    MeasureUnitImpl sourceUnit = MeasureUnitImpl::forIdentifier(x, status);
    if (status.errIfFailureAndReset("forIdentifier(\"%.*s\")", x.length(), x.data())) {
        return;
    }

    CharString targetIdent(y, status);
    MeasureUnitImpl targetUnit = MeasureUnitImpl::forIdentifier(y, status);
    if (status.errIfFailureAndReset("forIdentifier(\"%.*s\")", y.length(), y.data())) {
        return;
    }

    unitsTest->logln("Quantity (Category): \"%.*s\", "
                     "Expected value of \"1000 %.*s in %.*s\": %f, "
                     "commentConversionFormula: \"%.*s\", ",
                     quantity.length(), quantity.data(), x.length(), x.data(), y.length(), y.data(),
                     expected, commentConversionFormula.length(), commentConversionFormula.data());

    // Convertibility:
    auto convertibility = extractConvertibility(sourceUnit, targetUnit, *ctx->conversionRates, status);
    if (status.errIfFailureAndReset("extractConvertibility(<%s>, <%s>, ...)",
                                    sourceIdent.data(), targetIdent.data())) {
        return;
    }
    CharString msg;
    msg.append("convertible: ", status)
        .append(sourceIdent.data(), status)
        .append(" -> ", status)
        .append(targetIdent.data(), status);
    if (status.errIfFailureAndReset("msg construction")) {
        return;
    }
    unitsTest->assertNotEquals(msg.data(), UNCONVERTIBLE, convertibility);

    // Conversion:
    UnitsConverter converter(sourceUnit, targetUnit, *ctx->conversionRates, status);
    if (status.errIfFailureAndReset("UnitsConverter(<%s>, <%s>, ...)", sourceIdent.data(),
                                    targetIdent.data())) {
        return;
    }
    double got = converter.convert(1000);
    msg.clear();
    msg.append("Converting 1000 ", status).append(x, status).append(" to ", status).append(y, status);
    unitsTest->assertEqualsNear(msg.data(), expected, got, 0.0001 * expected);
    double inverted = converter.convertInverse(got);
    msg.clear();
    msg.append("Converting back to ", status).append(x, status).append(" from ", status).append(y, status);
    unitsTest->assertEqualsNear(msg.data(), 1000, inverted, 0.0001);
}

/**
 * Runs data-driven unit tests for unit conversion. It looks for the test cases
 * in source/test/testdata/cldr/units/unitsTest.txt, which originates in CLDR.
 */
void UnitsTest::testConverterWithCLDRTests() {
    const char *filename = "unitsTest.txt";
    const int32_t kNumFields = 5;
    char *fields[kNumFields][2];

    IcuTestErrorCode errorCode(*this, "UnitsTest::testConverterWithCLDRTests");
    const char *sourceTestDataPath = getSourceTestData(errorCode);
    if (errorCode.errIfFailureAndReset("unable to find the source/test/testdata "
                                       "folder (getSourceTestData())")) {
        return;
    }

    CharString path(sourceTestDataPath, errorCode);
    path.appendPathPart("cldr/units", errorCode);
    path.appendPathPart(filename, errorCode);

    ConversionRates rates(errorCode);
    UnitsTestContext ctx = {this, &rates};
    u_parseDelimitedFile(path.data(), ';', fields, kNumFields, unitsTestDataLineFn, &ctx, errorCode);
    if (errorCode.errIfFailureAndReset("error parsing %s: %s\n", path.data(), u_errorName(errorCode))) {
        return;
    }
}

void UnitsTest::testComplexUnitsConverter() {
    IcuTestErrorCode status(*this, "UnitsTest::testComplexUnitsConverter");

    // DBL_EPSILON is aproximately 2.22E-16, and is the precision of double for
    // values in the range [1.0, 2.0), but half the precision of double for
    // [2.0, 4.0).
    U_ASSERT(1.0 + DBL_EPSILON > 1.0);
    U_ASSERT(2.0 - DBL_EPSILON < 2.0);
    U_ASSERT(2.0 + DBL_EPSILON == 2.0);

    struct TestCase {
        const char* msg;
        const char* input;
        const char* output;
        double value;
        Measure expected[2];
        int32_t expectedCount;
        // For mixed units, accuracy of the smallest unit
        double accuracy;
    } testCases[]{
        // Significantly less than 2.0.
        {"1.9999",
         "foot",
         "foot-and-inch",
         1.9999,
         {Measure(1, MeasureUnit::createFoot(status), status),
          Measure(11.9988, MeasureUnit::createInch(status), status)},
         2,
         0},

        // A minimal nudge under 2.0, rounding up to 2.0 ft, 0 in.
        {"2-eps",
         "foot",
         "foot-and-inch",
         2.0 - DBL_EPSILON,
         {Measure(2, MeasureUnit::createFoot(status), status),
          Measure(0, MeasureUnit::createInch(status), status)},
         2,
         0},

        // A slightly bigger nudge under 2.0, *not* rounding up to 2.0 ft!
        {"2-3eps",
         "foot",
         "foot-and-inch",
         2.0 - 3 * DBL_EPSILON,
         {Measure(1, MeasureUnit::createFoot(status), status),
          // We expect 12*3*DBL_EPSILON inches (7.92e-15) less than 12.
          Measure(12 - 36 * DBL_EPSILON, MeasureUnit::createInch(status), status)},
         2,
         // Might accuracy be lacking with some compilers or on some systems? In
         // case it is somehow lacking, we'll allow a delta of 12 * DBL_EPSILON.
         12 * DBL_EPSILON},

        // Testing precision with meter and light-year.
        //
        // DBL_EPSILON light-years, ~2.22E-16 light-years, is ~2.1 meters
        // (maximum precision when exponent is 0).
        //
        // 1e-16 light years is 0.946073 meters.

        // A 2.1 meter nudge under 2.0 light years, rounding up to 2.0 ly, 0 m.
        {"2-eps",
         "light-year",
         "light-year-and-meter",
         2.0 - DBL_EPSILON,
         {Measure(2, MeasureUnit::createLightYear(status), status),
          Measure(0, MeasureUnit::createMeter(status), status)},
         2,
         0},

        // A 2.1 meter nudge under 1.0 light years, rounding up to 1.0 ly, 0 m.
        {"1-eps",
         "light-year",
         "light-year-and-meter",
         1.0 - DBL_EPSILON,
         {Measure(1, MeasureUnit::createLightYear(status), status),
          Measure(0, MeasureUnit::createMeter(status), status)},
         2,
         0},

        // 1e-15 light years is 9.46073 meters (calculated using "bc" and the
        // CLDR conversion factor). With double-precision maths in C++, we get
        // 10.5. In this case, we're off by a bit more than 1 meter. With Java
        // BigDecimal, we get accurate results.
        {"1 + 1e-15",
         "light-year",
         "light-year-and-meter",
         1.0 + 1e-15,
         {Measure(1, MeasureUnit::createLightYear(status), status),
          Measure(9.46073, MeasureUnit::createMeter(status), status)},
         2,
         1.5 /* meters, precision */},

        // 2.1 meters more than 1 light year is not rounded away.
        {"1 + eps",
         "light-year",
         "light-year-and-meter",
         1.0 + DBL_EPSILON,
         {Measure(1, MeasureUnit::createLightYear(status), status),
          Measure(2.1, MeasureUnit::createMeter(status), status)},
         2,
         0.001},
    };
    status.assertSuccess();

    ConversionRates rates(status);
    MeasureUnit input, output;
    MeasureUnitImpl tempInput, tempOutput;
    MaybeStackVector<Measure> measures;
    for (const TestCase &testCase : testCases) {
        input = MeasureUnit::forIdentifier(testCase.input, status);
        output = MeasureUnit::forIdentifier(testCase.output, status);
        const MeasureUnitImpl& inputImpl = MeasureUnitImpl::forMeasureUnit(input, tempInput, status);
        const MeasureUnitImpl& outputImpl = MeasureUnitImpl::forMeasureUnit(output, tempOutput, status);
        auto converter = ComplexUnitsConverter(inputImpl, outputImpl, rates, status);
        measures = converter.convert(testCase.value, nullptr, status);

        CharString msg;
        msg.append(testCase.msg, status);
        msg.append(" ", status);
        msg.append(testCase.input, status);
        msg.append(" -> ", status);
        msg.append(testCase.output, status);

        CharString msgCount(msg, status);
        msgCount.append(", measures.length()", status);
        assertEquals(msgCount.data(), testCase.expectedCount, measures.length());
        for (int i = 0; i < measures.length() && i < testCase.expectedCount; i++) {
            if (i == testCase.expectedCount-1) {
                assertEqualsNear(msg.data(), testCase.expected[i].getNumber().getDouble(status),
                                 measures[i]->getNumber().getDouble(status), testCase.accuracy);
            } else {
                assertEquals(msg.data(), testCase.expected[i].getNumber().getDouble(status),
                             measures[i]->getNumber().getDouble(status));
            }
            assertEquals(msg.data(), testCase.expected[i].getUnit().getIdentifier(),
                         measures[i]->getUnit().getIdentifier());
        }
    }
    status.assertSuccess();

    // TODO(icu-units#63): test negative numbers!
}

void UnitsTest::testComplexUnitsConverterSorting() {
    IcuTestErrorCode status(*this, "UnitsTest::testComplexUnitsConverterSorting");
    ConversionRates conversionRates(status);

    status.assertSuccess();

    struct TestCase {
        const char *msg;
        const char *input;
        const char *output;
        double inputValue;
        Measure expected[3];
        int32_t expectedCount;
        // For mixed units, accuracy of the smallest unit
        double accuracy;
    } testCases[]{{"inch-and-foot",
                   "meter",
                   "inch-and-foot",
                   10.0,
                   {
                       Measure(9.70079, MeasureUnit::createInch(status), status),
                       Measure(32, MeasureUnit::createFoot(status), status),
                       Measure(0, MeasureUnit::createBit(status), status),
                   },
                   2,
                   0.00001},
                  {"inch-and-yard-and-foot",
                   "meter",
                   "inch-and-yard-and-foot",
                   100.0,
                   {
                       Measure(1.0079, MeasureUnit::createInch(status), status),
                       Measure(109, MeasureUnit::createYard(status), status),
                       Measure(1, MeasureUnit::createFoot(status), status),
                   },
                   3,
                   0.0001}};

    for (const auto &testCase : testCases) {
        MeasureUnitImpl inputImpl = MeasureUnitImpl::forIdentifier(testCase.input, status);
        MeasureUnitImpl outputImpl = MeasureUnitImpl::forIdentifier(testCase.output, status);
        ComplexUnitsConverter converter(inputImpl, outputImpl, conversionRates, status);

        auto actual = converter.convert(testCase.inputValue, nullptr, status);

        for (int i = 0; i < testCase.expectedCount; i++) {
            assertEquals(testCase.msg, testCase.expected[i].getUnit().getIdentifier(),
                         actual[i]->getUnit().getIdentifier());

            if (testCase.expected[i].getNumber().getType() == Formattable::Type::kInt64) {
                assertEquals(testCase.msg, testCase.expected[i].getNumber().getInt64(),
                             actual[i]->getNumber().getInt64());
            } else {
                assertEqualsNear(testCase.msg, testCase.expected[i].getNumber().getDouble(),
                                 actual[i]->getNumber().getDouble(), testCase.accuracy);
            }
        }
    }

    MeasureUnitImpl source = MeasureUnitImpl::forIdentifier("meter", status);
    MeasureUnitImpl target = MeasureUnitImpl::forIdentifier("inch-and-foot", status);

    ComplexUnitsConverter complexConverter(source, target, conversionRates, status);
    auto measures = complexConverter.convert(10.0, nullptr, status);

    if (2 == measures.length()) {
        assertEquals("inch-and-foot unit 0", "inch", measures[0]->getUnit().getIdentifier());
        assertEquals("inch-and-foot unit 1", "foot", measures[1]->getUnit().getIdentifier());

        assertEqualsNear("inch-and-foot value 0", 9.7008, measures[0]->getNumber().getDouble(), 0.0001);
        assertEqualsNear("inch-and-foot value 1", 32, measures[1]->getNumber().getInt64(), 0.00001);
    }
}

/**
 * This class represents the output fields from unitPreferencesTest.txt. Please
 * see the documentation at the top of that file for details.
 *
 * For "mixed units" output, there are more (repeated) output fields. The last
 * output unit has the expected output specified as both a rational fraction and
 * a decimal fraction. This class ignores rational fractions, and expects to
 * find a decimal fraction for each output unit.
 */
class ExpectedOutput {
  public:
    // Counts number of units in the output. When this is more than one, we have
    // "mixed units" in the expected output.
    int _compoundCount = 0;

    // Counts how many fields were skipped: we expect to skip only one per
    // output unit type (the rational fraction).
    int _skippedFields = 0;

    // The expected output units: more than one for "mixed units".
    MeasureUnit _measureUnits[3];

    // The amounts of each of the output units.
    double _amounts[3];

    /**
     * Parse an expected output field from the test data file.
     *
     * @param output may be a string representation of an integer, a rational
     * fraction, a decimal fraction, or it may be a unit identifier. Whitespace
     * should already be trimmed. This function ignores rational fractions,
     * saving only decimal fractions and their unit identifiers.
     * @return true if the field was successfully parsed, false if parsing
     * failed.
     */
    void parseOutputField(StringPiece output, UErrorCode &errorCode) {
        if (U_FAILURE(errorCode)) return;
        DecimalQuantity dqOutputD;

        dqOutputD.setToDecNumber(output, errorCode);
        if (U_SUCCESS(errorCode)) {
            _amounts[_compoundCount] = dqOutputD.toDouble();
            return;
        } else if (errorCode == U_DECIMAL_NUMBER_SYNTAX_ERROR) {
            // Not a decimal fraction, it might be a rational fraction or a unit
            // identifier: continue.
            errorCode = U_ZERO_ERROR;
        } else {
            // Unexpected error, so we propagate it.
            return;
        }

        _measureUnits[_compoundCount] = MeasureUnit::forIdentifier(output, errorCode);
        if (U_SUCCESS(errorCode)) {
            _compoundCount++;
            _skippedFields = 0;
            return;
        }
        _skippedFields++;
        if (_skippedFields < 2) {
            // We are happy skipping one field per output unit: we want to skip
            // rational fraction fields like "11 / 10".
            errorCode = U_ZERO_ERROR;
            return;
        } else {
            // Propagate the error.
            return;
        }
    }

    /**
     * Produces an output string for debug purposes.
     */
    std::string toDebugString() {
        std::string result;
        for (int i = 0; i < _compoundCount; i++) {
            result += std::to_string(_amounts[i]);
            result += " ";
            result += _measureUnits[i].getIdentifier();
            result += " ";
        }
        return result;
    }
};

// Checks a vector of Measure instances against ExpectedOutput.
void checkOutput(UnitsTest *unitsTest, const char *msg, ExpectedOutput expected,
                 const MaybeStackVector<Measure> &actual, double precision) {
    IcuTestErrorCode status(*unitsTest, "checkOutput");

    CharString testMessage("Test case \"", status);
    testMessage.append(msg, status);
    testMessage.append("\": expected output: ", status);
    testMessage.append(expected.toDebugString().c_str(), status);
    testMessage.append(", obtained output:", status);
    for (int i = 0; i < actual.length(); i++) {
        testMessage.append(" ", status);
        testMessage.append(std::to_string(actual[i]->getNumber().getDouble(status)), status);
        testMessage.append(" ", status);
        testMessage.appendInvariantChars(actual[i]->getUnit().getIdentifier(), status);
    }
    if (!unitsTest->assertEquals(testMessage.data(), expected._compoundCount, actual.length())) {
        return;
    };
    for (int i = 0; i < actual.length(); i++) {
        double permittedDiff = precision * expected._amounts[i];
        if (permittedDiff == 0) {
            // If 0 is expected, still permit a small delta.
            // TODO: revisit this experimentally chosen value:
            permittedDiff = 0.00000001;
        }
        unitsTest->assertEqualsNear(testMessage.data(), expected._amounts[i],
                                    actual[i]->getNumber().getDouble(status), permittedDiff);
    }
}

/**
 * Runs a single data-driven unit test for unit preferences.
 *
 * This is a UParseLineFn as required by u_parseDelimitedFile, intended for
 * parsing unitPreferencesTest.txt.
 */
void unitPreferencesTestDataLineFn(void *context, char *fields[][2], int32_t fieldCount,
                                   UErrorCode *pErrorCode) {
    if (U_FAILURE(*pErrorCode)) return;
    UnitsTest *unitsTest = (UnitsTest *)context;
    IcuTestErrorCode status(*unitsTest, "unitPreferencesTestDatalineFn");

    if (!unitsTest->assertTrue(u"unitPreferencesTestDataLineFn expects 9 fields for simple and 11 "
                               u"fields for compound. Other field counts not yet supported. ",
                               fieldCount == 9 || fieldCount == 11)) {
        return;
    }

    StringPiece quantity = trimField(fields[0]);
    StringPiece usage = trimField(fields[1]);
    StringPiece region = trimField(fields[2]);
    // Unused // StringPiece inputR = trimField(fields[3]);
    StringPiece inputD = trimField(fields[4]);
    StringPiece inputUnit = trimField(fields[5]);
    ExpectedOutput expected;
    for (int i = 6; i < fieldCount; i++) {
        expected.parseOutputField(trimField(fields[i]), status);
    }
    if (status.errIfFailureAndReset("parsing unitPreferencesTestData.txt test case: %s", fields[0][0])) {
        return;
    }

    DecimalQuantity dqInputD;
    dqInputD.setToDecNumber(inputD, status);
    if (status.errIfFailureAndReset("parsing decimal quantity: \"%.*s\"", inputD.length(),
                                    inputD.data())) {
        return;
    }
    double inputAmount = dqInputD.toDouble();

    MeasureUnit inputMeasureUnit = MeasureUnit::forIdentifier(inputUnit, status);
    if (status.errIfFailureAndReset("forIdentifier(\"%.*s\")", inputUnit.length(), inputUnit.data())) {
        return;
    }

    unitsTest->logln("Quantity (Category): \"%.*s\", Usage: \"%.*s\", Region: \"%.*s\", "
                     "Input: \"%f %s\", Expected Output: %s",
                     quantity.length(), quantity.data(), usage.length(), usage.data(), region.length(),
                     region.data(), inputAmount, inputMeasureUnit.getIdentifier(),
                     expected.toDebugString().c_str());

    if (U_FAILURE(status)) {
        return;
    }

    UnitsRouter router(inputMeasureUnit, region, usage, status);
    if (status.errIfFailureAndReset("UnitsRouter(<%s>, \"%.*s\", \"%.*s\", status)",
                                    inputMeasureUnit.getIdentifier(), region.length(), region.data(),
                                    usage.length(), usage.data())) {
        return;
    }

    CharString msg(quantity, status);
    msg.append(" ", status);
    msg.append(usage, status);
    msg.append(" ", status);
    msg.append(region, status);
    msg.append(" ", status);
    msg.append(inputD, status);
    msg.append(" ", status);
    msg.append(inputMeasureUnit.getIdentifier(), status);
    if (status.errIfFailureAndReset("Failure before router.route")) {
        return;
    }
    RouteResult routeResult = router.route(inputAmount, nullptr, status);
    if (status.errIfFailureAndReset("router.route(inputAmount, ...)")) {
        return;
    }
    // TODO: revisit this experimentally chosen precision:
    checkOutput(unitsTest, msg.data(), expected, routeResult.measures, 0.0000000001);
}

/**
 * Parses the format used by unitPreferencesTest.txt, calling lineFn for each
 * line.
 *
 * This is a modified version of u_parseDelimitedFile, customized for
 * unitPreferencesTest.txt, due to it having a variable number of fields per
 * line.
 */
void parsePreferencesTests(const char *filename, char delimiter, char *fields[][2],
                           int32_t maxFieldCount, UParseLineFn *lineFn, void *context,
                           UErrorCode *pErrorCode) {
    FileStream *file;
    char line[10000];
    char *start, *limit;
    int32_t i;

    if (U_FAILURE(*pErrorCode)) {
        return;
    }

    if (fields == NULL || lineFn == NULL || maxFieldCount <= 0) {
        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    if (filename == NULL || *filename == 0 || (*filename == '-' && filename[1] == 0)) {
        filename = NULL;
        file = T_FileStream_stdin();
    } else {
        file = T_FileStream_open(filename, "r");
    }
    if (file == NULL) {
        *pErrorCode = U_FILE_ACCESS_ERROR;
        return;
    }

    while (T_FileStream_readLine(file, line, sizeof(line)) != NULL) {
        /* remove trailing newline characters */
        u_rtrim(line);

        start = line;
        *pErrorCode = U_ZERO_ERROR;

        /* skip this line if it is empty or a comment */
        if (*start == 0 || *start == '#') {
            continue;
        }

        /* remove in-line comments */
        limit = uprv_strchr(start, '#');
        if (limit != NULL) {
            /* get white space before the pound sign */
            while (limit > start && U_IS_INV_WHITESPACE(*(limit - 1))) {
                --limit;
            }

            /* truncate the line */
            *limit = 0;
        }

        /* skip lines with only whitespace */
        if (u_skipWhitespace(start)[0] == 0) {
            continue;
        }

        /* for each field, call the corresponding field function */
        for (i = 0; i < maxFieldCount; ++i) {
            /* set the limit pointer of this field */
            limit = start;
            while (*limit != delimiter && *limit != 0) {
                ++limit;
            }

            /* set the field start and limit in the fields array */
            fields[i][0] = start;
            fields[i][1] = limit;

            /* set start to the beginning of the next field, if any */
            start = limit;
            if (*start != 0) {
                ++start;
            } else {
                break;
            }
        }
        if (i == maxFieldCount) {
            *pErrorCode = U_PARSE_ERROR;
        }
        int fieldCount = i + 1;

        /* call the field function */
        lineFn(context, fields, fieldCount, pErrorCode);
        if (U_FAILURE(*pErrorCode)) {
            break;
        }
    }

    if (filename != NULL) {
        T_FileStream_close(file);
    }
}

/**
 * Runs data-driven unit tests for unit preferences. It looks for the test cases
 * in source/test/testdata/cldr/units/unitPreferencesTest.txt, which originates
 * in CLDR.
 */
void UnitsTest::testUnitPreferencesWithCLDRTests() {
    const char *filename = "unitPreferencesTest.txt";
    const int32_t maxFields = 11;
    char *fields[maxFields][2];

    IcuTestErrorCode errorCode(*this, "UnitsTest::testUnitPreferencesWithCLDRTests");
    const char *sourceTestDataPath = getSourceTestData(errorCode);
    if (errorCode.errIfFailureAndReset("unable to find the source/test/testdata "
                                       "folder (getSourceTestData())")) {
        return;
    }

    CharString path(sourceTestDataPath, errorCode);
    path.appendPathPart("cldr/units", errorCode);
    path.appendPathPart(filename, errorCode);

    parsePreferencesTests(path.data(), ';', fields, maxFields, unitPreferencesTestDataLineFn, this,
                          errorCode);
    if (errorCode.errIfFailureAndReset("error parsing %s: %s\n", path.data(), u_errorName(errorCode))) {
        return;
    }
}

#endif /* #if !UCONFIG_NO_FORMATTING */
