
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { createChart, getECModel } from '../../core/utHelper';
import { EChartsType } from '@/src/echarts';
import CartesianAxisModel from '@/src/coord/cartesian/AxisModel';
import IntervalScale from '@/src/scale/Interval';
import { intervalScaleNiceTicks } from '@/src/scale/helper';
import { getPrecisionSafe } from '@/src/util/number';


describe('scale_interval', function () {

    let chart: EChartsType;
    beforeEach(function () {
        chart = createChart();
    });

    afterEach(function () {
        chart.dispose();
    });


    describe('extreme', function () {
        it('ticks_min_max', function () {

            const min = 0;
            const max = 54.090909;
            const splitNumber = 5;

            chart.setOption({
                xAxis: {},
                yAxis: {
                    type: 'value',
                    min: min,
                    max: max,
                    interval: max / splitNumber,
                    splitNumber: splitNumber
                },
                series: [{type: 'line', data: []}]
            });

            const yAxis = getECModel(chart).getComponent('yAxis', 0) as CartesianAxisModel;
            const scale = yAxis.axis.scale;
            const ticks = scale.getTicks();

            expect(ticks[0].value).toEqual(min);
            expect(ticks[ticks.length - 1].value).toEqual(max);
        });

        it('ticks_small_value', function () {
            chart.setOption({
                tooltip: {},
                xAxis: [
                    {
                        type: 'category',
                        data: ['Mon'],
                        axisTick: {
                            alignWithLabel: true
                        }
                    }
                ],
                yAxis: [
                    {
                        type: 'value'
                    }
                ],
                series: [
                    {
                        name: '',
                        type: 'bar',
                        data: [0.0000034]
                    }
                ]
            });

            const yAxis = getECModel(chart).getComponent('yAxis', 0) as CartesianAxisModel;
            const scale = yAxis.axis.scale as IntervalScale;
            const ticks = scale.getTicks();
            const labels = yAxis.axis.getViewLabels().map(function (item) {
                return item.formattedLabel;
            });

            const labelPrecisioned = scale.getLabel({ value: 0.0000005 }, { precision: 10 });

            expect(ticks.map(tick => tick.value)).toEqual(
                [0, 0.0000005, 0.000001, 0.0000015, 0.000002, 0.0000025, 0.000003, 0.0000035]
            );
            expect(labels).toEqual(
                // Should not be '5e-7'
                ['0', '0.0000005', '0.000001', '0.0000015', '0.000002', '0.0000025', '0.000003', '0.0000035']
            );
            expect(labelPrecisioned).toEqual('0.0000005000');
        });
    });


    describe('ticks', function () {

        function randomNumber(quantity: number): number {
            return (Math.random() - 0.5) * Math.pow(10, (Math.random() - 0.5) * quantity);
        }

        function doSingleTest(extent: [number, number], splitNumber: number): void {
            const result = intervalScaleNiceTicks(extent, splitNumber);
            const intervalPrecision = result.intervalPrecision;
            const resultInterval = result.interval;
            const niceTickExtent = result.niceTickExtent;

            expect(resultInterval).toBeFinite();
            expect(intervalPrecision).toBeFinite();
            expect(niceTickExtent[0]).toBeFinite();
            expect(niceTickExtent[1]).toBeFinite();

            expect(niceTickExtent[0]).toBeGreaterThanOrEqual(extent[0]);
            expect(niceTickExtent[1]).not.toBeGreaterThan(extent[1]);
            expect(niceTickExtent[1]).toBeGreaterThanOrEqual(niceTickExtent[1]);

            const interval = new IntervalScale();
            interval.setExtent(extent[0], extent[1]);
            interval.calcNiceExtent({
                fixMin: true,
                fixMax: true,
                splitNumber
            });
            const ticks = interval.getTicks();

            expect(ticks.length > 0);
            expect(ticks[0].value).toEqual(extent[0]);
            expect(ticks[ticks.length - 1].value).toEqual(extent[1]);

            for (let i = 1; i < ticks.length; i++) {
                expect(ticks[i - 1].value).not.toBeGreaterThanOrEqual(ticks[i].value);

                if (ticks[i].value !== extent[0] && ticks[i].value !== extent[1]) {
                    const tickPrecision = getPrecisionSafe(ticks[i].value);
                    expect(tickPrecision).not.toBeGreaterThan(intervalPrecision);
                }
            }
        }

        function doRandomTest(count: number, splitNumber: number, quantity: number): void {
            for (let i = 0; i < count; i++) {
                const extent: number[] = [];
                extent[0] = randomNumber(quantity);
                extent[1] = extent[0] + randomNumber(quantity);
                if (extent[1] === extent[0]) {
                    extent[1] = extent[0] + 1;
                }
                if (extent[0] > extent[1]) {
                    extent.reverse();
                }
                doSingleTest(extent as [number, number], splitNumber);
            }
        }

        it('cases', function () {
            doSingleTest([3.7210923755786733e-8, 176.4352516752083], 1);
            doSingleTest([1550932.3941785, 1550932.3941786], 5);
            doSingleTest([-3711126.9907707, -3711126.990770699], 5);
        });

        it('randomCover', function () {
            doRandomTest(500, 5, 20);
            doRandomTest(200, 1, 20);
        });
    });

});