// © 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 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.UnitConverter;
import com.ibm.icu.impl.units.UnitsRouter;
import com.ibm.icu.util.Measure;
import com.ibm.icu.util.MeasureUnit;
import org.junit.Test;

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 static org.junit.Assert.*;


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() {
        ConversionRates rates = new ConversionRates();
        MeasureUnit input = MeasureUnit.FOOT;
        MeasureUnit output = MeasureUnit.forIdentifier("foot-and-inch");
        final MeasureUnitImpl inputImpl = MeasureUnitImpl.forIdentifier(input.getIdentifier());
        final MeasureUnitImpl outputImpl = MeasureUnitImpl.forIdentifier(output.getIdentifier());
        ComplexUnitsConverter converter = new ComplexUnitsConverter(inputImpl, outputImpl, rates);

        // Significantly less than 2.0.
        List<Measure> measures = converter.convert(BigDecimal.valueOf(1.9999), null);
        assertEquals("measures length", 2, measures.size());
        assertEquals("1.9999: measures[0] value", BigDecimal.valueOf(1), measures.get(0).getNumber());
        assertEquals("1.9999: measures[0] unit", MeasureUnit.FOOT.getIdentifier(),
                measures.get(0).getUnit().getIdentifier());

        assertTrue("1.9999: measures[1] value", compareTwoBigDecimal(BigDecimal.valueOf(11.9988),
                BigDecimal.valueOf(measures.get(1).getNumber().doubleValue()), BigDecimal.valueOf(0.0001)));
        assertEquals("1.9999: measures[1] unit", MeasureUnit.INCH.getIdentifier(),
                measures.get(1).getUnit().getIdentifier());

        // TODO(icu-units#100): consider factoring out the set of tests to make
        // this function more data-driven, *after* dealing appropriately with
        // the C++ memory leaks that can be demonstrated by the C++ version of
        // this code.

        // A minimal nudge under 2.0.
        List<Measure> measures2 =
            converter.convert(BigDecimal.valueOf(2.0).subtract(ComplexUnitsConverter.EPSILON), null);
        assertEquals("measures length", 2, measures2.size());
        assertEquals("1 - eps: measures[0] value", BigDecimal.valueOf(2), measures2.get(0).getNumber());
        assertEquals("1 - eps: measures[0] unit", MeasureUnit.FOOT.getIdentifier(),
                measures2.get(0).getUnit().getIdentifier());
        assertEquals("1 - eps: measures[1] value", BigDecimal.ZERO, measures2.get(1).getNumber());
        assertEquals("1 - eps: measures[1] unit", MeasureUnit.INCH.getIdentifier(),
                measures2.get(1).getUnit().getIdentifier());

        // Testing precision with meter and light-year. 1e-16 light years is
        // 0.946073 meters, and double precision can provide only ~15 decimal
        // digits, so we don't expect to get anything less than 1 meter.

        // An epsilon's nudge under one light-year: should give 1 ly, 0 m.
        input = MeasureUnit.LIGHT_YEAR;
        output = MeasureUnit.forIdentifier("light-year-and-meter");
        final MeasureUnitImpl inputImpl3 = MeasureUnitImpl.forIdentifier(input.getIdentifier());
        final MeasureUnitImpl outputImpl3 = MeasureUnitImpl.forIdentifier(output.getIdentifier());

        ComplexUnitsConverter converter3 = new ComplexUnitsConverter(inputImpl3, outputImpl3, rates);

        List<Measure> measures3 =
            converter3.convert(BigDecimal.valueOf(2.0).subtract(ComplexUnitsConverter.EPSILON), null);
        assertEquals("measures length", 2, measures3.size());
        assertEquals("light-year test: measures[0] value", BigDecimal.valueOf(2), measures3.get(0).getNumber());
        assertEquals("light-year test: measures[0] unit", MeasureUnit.LIGHT_YEAR.getIdentifier(),
                measures3.get(0).getUnit().getIdentifier());
        assertEquals("light-year test: measures[1] value", BigDecimal.ZERO, measures3.get(1).getNumber());
        assertEquals("light-year test: measures[1] unit", MeasureUnit.METER.getIdentifier(),
                measures3.get(1).getUnit().getIdentifier());

        // 1e-15 light years is 9.46073 meters (calculated using "bc" and the CLDR
        // conversion factor). With double-precision maths, we get 10.5. In this
        // case, we're off by almost 1 meter.
        List<Measure> measures4 = converter3.convert(BigDecimal.valueOf(1.0 + 1e-15), null);
        assertEquals("measures length", 2, measures4.size());
        assertEquals("light-year test: measures[0] value", BigDecimal.ONE, measures4.get(0).getNumber());
        assertEquals("light-year test: measures[0] unit", MeasureUnit.LIGHT_YEAR.getIdentifier(),
                measures4.get(0).getUnit().getIdentifier());
        assertTrue("light-year test: measures[1] value", compareTwoBigDecimal(BigDecimal.valueOf(10),
                BigDecimal.valueOf(measures4.get(1).getNumber().doubleValue()),
                BigDecimal.valueOf(1)));
        assertEquals("light-year test: measures[1] unit", MeasureUnit.METER.getIdentifier(),
                measures4.get(1).getUnit().getIdentifier());

        // 2e-16 light years is 1.892146 meters. We consider this in the noise, and
        // thus expect a 0. (This test fails when 2e-16 is increased to 4e-16.)
        List<Measure> measures5 = converter3.convert(BigDecimal.valueOf(1.0 + 2e-17), null);
        assertEquals("measures length", 2, measures5.size());
        assertEquals("light-year test: measures[0] value", BigDecimal.ONE, measures5.get(0).getNumber());
        assertEquals("light-year test: measures[0] unit", MeasureUnit.LIGHT_YEAR.getIdentifier(),
                measures5.get(0).getUnit().getIdentifier());
        assertEquals("light-year test: measures[1] value", BigDecimal.valueOf(0.0),
                measures5.get(1).getNumber());
        assertEquals("light-year test: measures[1] unit", MeasureUnit.METER.getIdentifier(),
                measures5.get(1).getUnit().getIdentifier());

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


    @Test
    public void testComplexUnitConverterSorting() {

        MeasureUnitImpl source = MeasureUnitImpl.forIdentifier("meter");
        MeasureUnitImpl target = MeasureUnitImpl.forIdentifier("inch-and-foot");
        ConversionRates conversionRates = new ConversionRates();

        ComplexUnitsConverter complexConverter = new ComplexUnitsConverter(source, target, conversionRates);
        List<Measure> measures = complexConverter.convert(BigDecimal.valueOf(10.0), null);

        assertEquals(measures.size(), 2);
        assertEquals("inch-and-foot unit 0", "inch", measures.get(0).getUnit().getIdentifier());
        assertEquals("inch-and-foot unit 1", "foot", measures.get(1).getUnit().getIdentifier());

        assertEquals("inch-and-foot value 0", 9.7008, measures.get(0).getNumber().doubleValue(), 0.0001);
        assertEquals("inch-and-foot value 1", 32, measures.get(1).getNumber().doubleValue(), 0.0001);
    }


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

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

        TestData[] tests = {
                new TestData("meter", "foot", UnitConverter.Convertibility.CONVERTIBLE),
                new TestData("square-meter-per-square-hour", "hectare-per-square-second", UnitConverter.Convertibility.CONVERTIBLE),
                new TestData("hertz", "revolution-per-second", UnitConverter.Convertibility.CONVERTIBLE),
                new TestData("millimeter", "meter", UnitConverter.Convertibility.CONVERTIBLE),
                new TestData("yard", "meter", UnitConverter.Convertibility.CONVERTIBLE),
                new TestData("ounce-troy", "kilogram", UnitConverter.Convertibility.CONVERTIBLE),
                new TestData("percent", "portion", UnitConverter.Convertibility.CONVERTIBLE),
                new TestData("ofhg", "kilogram-per-square-meter-square-second", UnitConverter.Convertibility.CONVERTIBLE),

                new TestData("second-per-meter", "meter-per-second", UnitConverter.Convertibility.RECIPROCAL),
        };
        ConversionRates conversionRates = new ConversionRates();

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

    @Test
    public void testConverterForTemperature() {
        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 = {
                new TestData("celsius", "fahrenheit", 1000, 1832),
                new TestData("fahrenheit", "fahrenheit", 1000, 1000),
        };

        ConversionRates conversionRates = new ConversionRates();

        for (TestData test :
                tests) {
            UnitConverter converter = new UnitConverter(test.source, test.target, conversionRates);
            assertEquals(test.expected.doubleValue(), converter.convert(test.input).doubleValue(), (0.001));
        }

    }

    @Test
    public void testConverterFromUnitTests() 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";
        BufferedReader f = TestUtil.getDataReader("cldr/units/unitsTest.txt", codePage);
        ArrayList<TestCase> tests = new ArrayList<>();
        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) {
            UnitConverter converter = new UnitConverter(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 testUnitPreferencesFromUnitTests() throws IOException {
        class TestCase {

            final ArrayList<Pair<String, MeasureUnitImpl>> outputUnitInOrder = new ArrayList<>();
            final ArrayList<BigDecimal> expectedInOrder = new ArrayList<>();
            /**
             * Test Case Data
             */
            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));
                }
            }
        }

        // Read Test data from the unitPreferencesTest
        String codePage = "UTF-8";
        BufferedReader f = TestUtil.getDataReader("cldr/units/unitPreferencesTest.txt", codePage);
        ArrayList<TestCase> tests = new ArrayList<>();
        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).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(testCase.toString() + measures.toString());
                }
            }
        }
    }
}
