// © 2020 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.dev.test.impl;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.BufferedReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import com.ibm.icu.dev.test.TestUtil;
import com.ibm.icu.impl.Pair;
import com.ibm.icu.impl.units.ComplexUnitsConverter;
import com.ibm.icu.impl.units.ConversionRates;
import com.ibm.icu.impl.units.MeasureUnitImpl;
import com.ibm.icu.impl.units.UnitsConverter;
import com.ibm.icu.impl.units.UnitsRouter;
import com.ibm.icu.util.Measure;
import com.ibm.icu.util.MeasureUnit;


public class UnitsTest {

    public static boolean compareTwoBigDecimal(BigDecimal expected, BigDecimal actual, BigDecimal delta) {
        BigDecimal diff =
                expected.abs().compareTo(BigDecimal.ZERO) < 1 ?
                        expected.subtract(actual).abs() :
                        (expected.subtract(actual).divide(expected, MathContext.DECIMAL128)).abs();

        if (diff.compareTo(delta) == -1) return true;
        return false;
    }

    @Test
    public void testComplexUnitsConverter() {
        class TestCase {
            String input;
            String output;
            BigDecimal value;
            Measure[] expected;
            // For mixed units, accuracy of the smallest unit
            double accuracy;

            TestCase(String input, String output, BigDecimal value, Measure[] expected, double accuracy) {
                this.input = input;
                this.output = output;
                this.value = value;
                this.expected = expected;
                this.accuracy = accuracy;
            }
        }
        TestCase[] testCases = new TestCase[] {
            // Significantly less than 2.0.
            new TestCase(
                "foot", "foot-and-inch", BigDecimal.valueOf(1.9999),
                new Measure[] {new Measure(1, MeasureUnit.FOOT), new Measure(11.9988, MeasureUnit.INCH)},
                0),

            // A minimal nudge under 2.0, rounding up to 2.0 ft, 0 in.
            // TODO(icu-units#108): this matches double precision calculations
            // from C++, but BigDecimal is in use: do we want Java to be more
            // precise than C++?
            new TestCase(
                "foot", "foot-and-inch", BigDecimal.valueOf(2.0).subtract(ComplexUnitsConverter.EPSILON),
                new Measure[] {new Measure(2, MeasureUnit.FOOT), new Measure(0, MeasureUnit.INCH)}, 0),

            // A slightly bigger nudge under 2.0, *not* rounding up to 2.0 ft!
            new TestCase("foot", "foot-and-inch",
                         BigDecimal.valueOf(2.0).subtract(
                             ComplexUnitsConverter.EPSILON.multiply(BigDecimal.valueOf(3.0))),
                         new Measure[] {new Measure(1, MeasureUnit.FOOT),
                                        new Measure(BigDecimal.valueOf(12.0).subtract(
                                                        ComplexUnitsConverter.EPSILON.multiply(
                                                            BigDecimal.valueOf(36.0))),
                                                    MeasureUnit.INCH)},
                         0),

            // 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.
            // TODO(icu-units#108): this matches double precision calculations
            // from C++, but BigDecimal is in use: do we want Java to be more
            // precise than C++?
            new TestCase("light-year", "light-year-and-meter",
                         BigDecimal.valueOf(2.0).subtract(ComplexUnitsConverter.EPSILON),
                         new Measure[] {new Measure(2, MeasureUnit.LIGHT_YEAR),
                                        new Measure(0, MeasureUnit.METER)},
                         0),

            // // TODO(icu-units#108): figure out precision thresholds for BigDecimal?
            // // This test passes in C++ due to double-precision rounding.
            // // A 2.1 meter nudge under 1.0 light years, rounding up to 1.0 ly, 0 m.
            // new TestCase("light-year", "light-year-and-meter",
            //              BigDecimal.valueOf(1.0).subtract(ComplexUnitsConverter.EPSILON),
            //              new Measure[] {new Measure(1, MeasureUnit.LIGHT_YEAR),
            //                             new Measure(0, MeasureUnit.METER)},
            //              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.
            new TestCase("light-year", "light-year-and-meter", BigDecimal.valueOf(1.0 + 1e-15),
                         new Measure[] {new Measure(1, MeasureUnit.LIGHT_YEAR),
                                        new Measure(9.46073, MeasureUnit.METER)},
                         0 /* meters, precision */),

            // TODO(icu-units#108): reconsider whether epsilon rounding is desirable:
            //
            // 2e-16 light years is 1.892146 meters. For C++ double, we consider
            // this in the noise, and thus expect a 0. (This test fails when
            // 2e-16 is increased to 4e-16.) For Java, using BigDecimal, we
            // actually get a good result.
            new TestCase("light-year", "light-year-and-meter", BigDecimal.valueOf(1.0 + 2e-16),
                         new Measure[] {new Measure(1, MeasureUnit.LIGHT_YEAR),
                                        new Measure(1.892146, MeasureUnit.METER)},
                         0),
        };

        ConversionRates rates = new ConversionRates();
        MeasureUnit input, output;
        List<Measure> measures;
        for (TestCase testCase : testCases) {
            input = MeasureUnit.forIdentifier(testCase.input);
            output = MeasureUnit.forIdentifier(testCase.output);
            final MeasureUnitImpl inputImpl = MeasureUnitImpl.forIdentifier(input.getIdentifier());
            final MeasureUnitImpl outputImpl = MeasureUnitImpl.forIdentifier(output.getIdentifier());
            ComplexUnitsConverter converter = new ComplexUnitsConverter(inputImpl, outputImpl, rates);
            measures = converter.convert(testCase.value, null).measures;

            assertEquals("measures length", testCase.expected.length, measures.size());
            int i = 0;
            for (Measure measure : measures) {
                double accuracy = 0.0;
                if (i == testCase.expected.length - 1) {
                    accuracy = testCase.accuracy;
                }
                assertTrue("input " + testCase.value + ", output measure " + i + ": expected " +
                               testCase.expected[i] + ", expected unit " +
                               testCase.expected[i].getUnit() + " got unit " + measure.getUnit(),
                           testCase.expected[i].getUnit().equals(measure.getUnit()));
                assertEquals("input " + testCase.value + ", output measure " + i + ": expected " +
                                 testCase.expected[i] + ", expected number " +
                                 testCase.expected[i].getNumber() + " got number " + measure.getNumber(),
                             testCase.expected[i].getNumber().doubleValue(),
                             measure.getNumber().doubleValue(), accuracy);
                i++;
            }
        }

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


    @Test
    public void testComplexUnitConverterSorting() {
        class TestCase {
            String message;
            String inputUnit;
            String outputUnit;
            double inputValue;
            Measure[] expectedMeasures;
            double accuracy;

            public TestCase(String message, String inputUnit, String outputUnit, double inputValue, Measure[] expectedMeasures, double accuracy) {
                this.message = message;
                this.inputUnit = inputUnit;
                this.outputUnit = outputUnit;
                this.inputValue = inputValue;
                this.expectedMeasures = expectedMeasures;
                this.accuracy = accuracy;
            }
        }

        TestCase[] testCases = new TestCase[]{
                new TestCase(
                        "inch-and-foot",
                        "meter",
                        "inch-and-foot",
                        10.0,
                        new Measure[]{
                                new Measure(9.70079, MeasureUnit.INCH),
                                new Measure(32, MeasureUnit.FOOT),
                        },
                        0.0001
                ),
                new TestCase(
                        "inch-and-yard-and-foot",
                        "meter",
                        "inch-and-yard-and-foot",
                        100.0,
                        new Measure[]{
                                new Measure(1.0079, MeasureUnit.INCH),
                                new Measure(109, MeasureUnit.YARD),
                                new Measure(1, MeasureUnit.FOOT),
                        },
                        0.0001
                ),
        };

        ConversionRates conversionRates = new ConversionRates();
        for (TestCase testCase : testCases) {
            MeasureUnitImpl input = MeasureUnitImpl.forIdentifier(testCase.inputUnit);
            MeasureUnitImpl output = MeasureUnitImpl.forIdentifier(testCase.outputUnit);

            ComplexUnitsConverter converter = new ComplexUnitsConverter(input, output, conversionRates);
            List<Measure> actualMeasures = converter.convert(BigDecimal.valueOf(testCase.inputValue), null).measures;

            assertEquals(testCase.message, testCase.expectedMeasures.length, actualMeasures.size());
            for (int i = 0; i < testCase.expectedMeasures.length; i++) {
                assertEquals(testCase.message, testCase.expectedMeasures[i].getUnit(), actualMeasures.get(i).getUnit());
                assertEquals(testCase.message,
                        testCase.expectedMeasures[i].getNumber().doubleValue(),
                        actualMeasures.get(i).getNumber().doubleValue(),
                        testCase.accuracy);
            }
        }
    }


    @Test
    public void testExtractConvertibility() {
        class TestData {
            MeasureUnitImpl source;
            MeasureUnitImpl target;
            UnitsConverter.Convertibility expected;

            TestData(String source, String target, UnitsConverter.Convertibility convertibility) {
                this.source = MeasureUnitImpl.UnitsParser.parseForIdentifier(source);
                this.target = MeasureUnitImpl.UnitsParser.parseForIdentifier(target);
                this.expected = convertibility;
            }
        }

        TestData[] tests = {
                new TestData("meter", "foot", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("kilometer", "foot", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("hectare", "square-foot", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("kilometer-per-second", "second-per-meter", UnitsConverter.Convertibility.RECIPROCAL),
                new TestData("square-meter", "square-foot", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("kilometer-per-second", "foot-per-second", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("square-hectare", "pow4-foot", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("square-kilometer-per-second", "second-per-square-meter", UnitsConverter.Convertibility.RECIPROCAL),
                new TestData("cubic-kilometer-per-second-meter", "second-per-square-meter", UnitsConverter.Convertibility.RECIPROCAL),
                new TestData("square-meter-per-square-hour", "hectare-per-square-second", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("hertz", "revolution-per-second", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("millimeter", "meter", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("yard", "meter", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("ounce-troy", "kilogram", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("percent", "portion", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("ofhg", "kilogram-per-square-meter-square-second", UnitsConverter.Convertibility.CONVERTIBLE),
                new TestData("second-per-meter", "meter-per-second", UnitsConverter.Convertibility.RECIPROCAL),
        };
        ConversionRates conversionRates = new ConversionRates();

        for (TestData test :
                tests) {
            assertEquals(test.expected, UnitsConverter.extractConvertibility(test.source, test.target, conversionRates));
        }
    }

    @Test
    public void testConverter() {
        class TestData {
            MeasureUnitImpl source;
            MeasureUnitImpl target;
            BigDecimal input;
            BigDecimal expected;

            TestData(String source, String target, double input, double expected) {
                this.source = MeasureUnitImpl.UnitsParser.parseForIdentifier(source);
                this.target = MeasureUnitImpl.UnitsParser.parseForIdentifier(target);
                this.input = BigDecimal.valueOf(input);
                this.expected = BigDecimal.valueOf(expected);
            }
        }
        TestData[] tests = {
                // SI Prefixes
                new TestData("gram", "kilogram", 1.0, 0.001),
                new TestData("milligram", "kilogram", 1.0, 0.000001),
                new TestData("microgram", "kilogram", 1.0, 0.000000001),
                new TestData("megagram", "gram", 1.0, 1000000),
                new TestData("megagram", "kilogram", 1.0, 1000),
                new TestData("gigabyte", "byte", 1.0, 1000000000),
                new TestData("megawatt", "watt", 1.0, 1000000),
                new TestData("megawatt", "kilowatt", 1.0, 1000),
                // Binary Prefixes
                new TestData("kilobyte", "byte", 1, 1000),
                new TestData("kibibyte", "byte", 1, 1024),
                new TestData("mebibyte", "byte", 1, 1048576),
                new TestData("gibibyte", "kibibyte", 1, 1048576),
                new TestData("pebibyte", "tebibyte", 4, 4096),
                new TestData("zebibyte", "pebibyte", 1.0/16, 65536.0),
                new TestData("yobibyte", "exbibyte", 1, 1048576),
                // Mass
                new TestData("gram", "kilogram", 1.0, 0.001),
                new TestData("pound", "kilogram", 1.0, 0.453592),
                new TestData("pound", "kilogram", 2.0, 0.907185),
                new TestData("ounce", "pound", 16.0, 1.0),
                new TestData("ounce", "kilogram", 16.0, 0.453592),
                new TestData("ton", "pound", 1.0, 2000),
                new TestData("stone", "pound", 1.0, 14),
                new TestData("stone", "kilogram", 1.0, 6.35029),
                // Temperature
                new TestData("celsius", "fahrenheit", 0.0, 32.0),
                new TestData("celsius", "fahrenheit", 10.0, 50.0),
                new TestData("celsius", "fahrenheit", 1000, 1832),
                new TestData("fahrenheit", "celsius", 32.0, 0.0),
                new TestData("fahrenheit", "celsius", 89.6, 32),
                new TestData("fahrenheit", "fahrenheit", 1000, 1000),
                new TestData("kelvin", "fahrenheit", 0.0, -459.67),
                new TestData("kelvin", "fahrenheit", 300, 80.33),
                new TestData("kelvin", "celsius", 0.0, -273.15),
                new TestData("kelvin", "celsius", 300.0, 26.85),
                // Area
                new TestData("square-meter", "square-yard", 10.0, 11.9599),
                new TestData("hectare", "square-yard", 1.0, 11959.9),
                new TestData("square-mile", "square-foot", 0.0001, 2787.84),
                new TestData("hectare", "square-yard", 1.0, 11959.9),
                new TestData("hectare", "square-meter", 1.0, 10000),
                new TestData("hectare", "square-meter", 0.0, 0.0),
                new TestData("square-mile", "square-foot", 0.0001, 2787.84),
                new TestData("square-yard", "square-foot", 10, 90),
                new TestData("square-yard", "square-foot", 0, 0),
                new TestData("square-yard", "square-foot", 0.000001, 0.000009),
                new TestData("square-mile", "square-foot", 0.0, 0.0),
        };

        ConversionRates conversionRates = new ConversionRates();
        for (TestData test : tests) {
            UnitsConverter converter = new UnitsConverter(test.source, test.target, conversionRates);
            double maxDelta = 1e-6 * Math.abs(test.expected.doubleValue());
            if (test.expected.doubleValue() == 0) {
                maxDelta = 1e-12;
            }
            assertEquals("testConverter: " + test.source + " to " + test.target,
                         test.expected.doubleValue(), converter.convert(test.input).doubleValue(),
                         maxDelta);
        }
    }

    @Test
    public void testConverterWithCLDRTests() throws IOException {
        class TestCase {
            String category;
            String sourceString;
            String targetString;
            MeasureUnitImpl source;
            MeasureUnitImpl target;
            BigDecimal input;
            BigDecimal expected;

            TestCase(String line) {
                String[] fields = line
                        .replaceAll(" ", "") // Remove all the spaces.
                        .replaceAll(",", "") // Remove all the commas.
                        .replaceAll("\t", "")
                        .split(";");

                this.category = fields[0].replaceAll(" ", "");
                this.sourceString = fields[1];
                this.targetString = fields[2];
                this.source = MeasureUnitImpl.UnitsParser.parseForIdentifier(fields[1]);
                this.target = MeasureUnitImpl.UnitsParser.parseForIdentifier(fields[2]);
                this.input = BigDecimal.valueOf(1000);
                this.expected = new BigDecimal(fields[4]);
            }
        }

        String codePage = "UTF-8";
        ArrayList<TestCase> tests = new ArrayList<>();
        try (BufferedReader f = TestUtil.getDataReader("cldr/units/unitsTest.txt", codePage)) {
            while (true) {
                String line = f.readLine();
                if (line == null) break;
                if (line.isEmpty() || line.startsWith("#")) continue;
                tests.add(new TestCase(line));
            }
        }

        ConversionRates conversionRates = new ConversionRates();

        for (TestCase testCase :
                tests) {
            UnitsConverter converter = new UnitsConverter(testCase.source, testCase.target, conversionRates);
            BigDecimal got = converter.convert(testCase.input);
            if (compareTwoBigDecimal(testCase.expected, got, BigDecimal.valueOf(0.000001))) {
                continue;
            } else {
                fail(new StringBuilder()
                        .append(testCase.category)
                        .append(": Converting 1000 ")
                        .append(testCase.sourceString)
                        .append(" to ")
                        .append(testCase.targetString)
                        .append(", got ")
                        .append(got)
                        .append(", expected ")
                        .append(testCase.expected.toString())
                        .toString());
            }
            BigDecimal inverted = converter.convertInverse(testCase.input);
            if (compareTwoBigDecimal(BigDecimal.valueOf(1000), inverted, BigDecimal.valueOf(0.000001))) {
                continue;
            } else {
                fail(new StringBuilder()
                .append("Converting back to ")
                .append(testCase.sourceString)
                .append(" from ")
                .append(testCase.targetString)
                .append(": got ")
                .append(inverted)
                .append(", expected 1000")
                .toString());
            }
        }
    }

    @Test
    public void testUnitPreferencesWithCLDRTests() throws IOException {
        class TestCase {

            // TODO: content of outputUnitInOrder isn't checked? Only size?
            final ArrayList<Pair<String, MeasureUnitImpl>> outputUnitInOrder = new ArrayList<>();
            final ArrayList<BigDecimal> expectedInOrder = new ArrayList<>();
            /**
             * Test Case Data
             */
            @SuppressWarnings("unused")
            String category;
            String usage;
            String region;
            Pair<String, MeasureUnitImpl> inputUnit;
            BigDecimal input;

            TestCase(String line) {
                String[] fields = line
                        .replaceAll(" ", "") // Remove all the spaces.
                        .replaceAll(",", "") // Remove all the commas.
                        .replaceAll("\t", "")
                        .split(";");

                String category = fields[0];
                String usage = fields[1];
                String region = fields[2];
                String inputValue = fields[4];
                String inputUnit = fields[5];
                ArrayList<Pair<String, String>> outputs = new ArrayList<>();

                for (int i = 6; i < fields.length - 2; i += 2) {
                    if (i == fields.length - 3) { // last field
                        outputs.add(Pair.of(fields[i + 2], fields[i + 1]));
                    } else {
                        outputs.add(Pair.of(fields[i + 1], fields[i]));
                    }
                }

                this.insertData(category, usage, region, inputUnit, inputValue, outputs);
            }

            private void insertData(String category,
                                    String usage,
                                    String region,
                                    String inputUnitString,
                                    String inputValue,
                                    ArrayList<Pair<String, String>> outputs /* Unit Identifier, expected value */) {
                this.category = category;
                this.usage = usage;
                this.region = region;
                this.inputUnit = Pair.of(inputUnitString, MeasureUnitImpl.UnitsParser.parseForIdentifier(inputUnitString));
                this.input = new BigDecimal(inputValue);
                for (Pair<String, String> output :
                        outputs) {
                    outputUnitInOrder.add(Pair.of(output.first, MeasureUnitImpl.UnitsParser.parseForIdentifier(output.first)));
                    expectedInOrder.add(new BigDecimal(output.second));
                }
            }

            public String toString() {
                return "TestCase: " + category + ", " + usage + ", " + region +
                    "; Input: " + input + " " + inputUnit.first + "; Expected Values: " + expectedInOrder;
            }
        }

        // Read Test data from the unitPreferencesTest
        String codePage = "UTF-8";
        ArrayList<TestCase> tests = new ArrayList<>();

        try (BufferedReader f = TestUtil.getDataReader("cldr/units/unitPreferencesTest.txt", codePage)) {
            while (true) {
                String line = f.readLine();
                if (line == null) break;
                if (line.isEmpty() || line.startsWith("#")) continue;
                tests.add(new TestCase(line));
            }
        }

        for (TestCase testCase :
                tests) {
            UnitsRouter router = new UnitsRouter(testCase.inputUnit.second, testCase.region, testCase.usage);
            List<Measure> measures = router.route(testCase.input, null).complexConverterResult.measures;

            assertEquals("Measures size must be the same as expected units",
                    measures.size(), testCase.expectedInOrder.size());
            assertEquals("Measures size must be the same as output units",
                    measures.size(), testCase.outputUnitInOrder.size());


            for (int i = 0; i < measures.size(); i++) {
                if (!UnitsTest
                        .compareTwoBigDecimal(testCase.expectedInOrder.get(i),
                                BigDecimal.valueOf(measures.get(i).getNumber().doubleValue()),
                                BigDecimal.valueOf(0.00001))) {
                    fail("Test failed: " + testCase + "; Got unexpected result: " + measures);
                }
            }
        }
    }
}
