/*
* 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.
*/

// TODO
// ??? refactor? check the outer usage of data provider.
// merge with defaultDimValueGetter?

import {isTypedArray, extend, assert, each, isObject, bind} from 'zrender/src/core/util';
import {getDataItemValue} from '../../util/model';
import { createSourceFromSeriesDataOption, Source, isSourceInstance } from '../Source';
import {ArrayLike, Dictionary} from 'zrender/src/core/types';
import {
    SOURCE_FORMAT_ORIGINAL,
    SOURCE_FORMAT_OBJECT_ROWS,
    SOURCE_FORMAT_KEYED_COLUMNS,
    SOURCE_FORMAT_TYPED_ARRAY,
    SOURCE_FORMAT_ARRAY_ROWS,
    SERIES_LAYOUT_BY_COLUMN,
    SERIES_LAYOUT_BY_ROW,
    DimensionName, DimensionIndex, OptionSourceData,
    DimensionIndexLoose, OptionDataItem, OptionDataValue, SourceFormat, SeriesLayoutBy, ParsedValue
} from '../../util/types';
import List from '../List';

export interface DataProvider {
    /**
     * true: all of the value are in primitive type (in type `OptionDataValue`).
     * false: Not sure whether any of them is non primitive type (in type `OptionDataItemObject`).
     *     Like `data: [ { value: xx, itemStyle: {...} }, ...]`
     *     At present it only happen in `SOURCE_FORMAT_ORIGINAL`.
     */
    pure?: boolean;
    /**
     * If data is persistent and will not be released after use.
     */
    persistent?: boolean;

    getSource(): Source;
    count(): number;
    getItem(idx: number, out?: OptionDataItem): OptionDataItem;
    fillStorage?(
        start: number,
        end: number,
        out: ArrayLike<ParsedValue>[],
        extent: number[][]
    ): void
    appendData?(newData: ArrayLike<OptionDataItem>): void;
    clean?(): void;
}


let providerMethods: Dictionary<any>;
let mountMethods: (provider: DefaultDataProvider, data: OptionSourceData, source: Source) => void;

export interface DefaultDataProvider {
    fillStorage?(
        start: number,
        end: number,
        out: ArrayLike<ParsedValue>[],
        extent: number[][]
    ): void
}
/**
 * If normal array used, mutable chunk size is supported.
 * If typed array used, chunk size must be fixed.
 */
export class DefaultDataProvider implements DataProvider {

    private _source: Source;

    private _data: OptionSourceData;

    private _offset: number;

    private _dimSize: number;

    pure: boolean;

    persistent: boolean;

    static protoInitialize = (function () {
        // PENDING: To avoid potential incompat (e.g., prototype
        // is visited somewhere), still init them on prototype.
        const proto = DefaultDataProvider.prototype;
        proto.pure = false;
        proto.persistent = true;
    })();


    constructor(sourceParam: Source | OptionSourceData, dimSize?: number) {
        // let source: Source;
        const source: Source = !isSourceInstance(sourceParam)
            ? createSourceFromSeriesDataOption(sourceParam as OptionSourceData)
            : sourceParam as Source;

        // declare source is Source;
        this._source = source;
        const data = this._data = source.data;

        // Typed array. TODO IE10+?
        if (source.sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
            if (__DEV__) {
                if (dimSize == null) {
                    throw new Error('Typed array data must specify dimension size');
                }
            }
            this._offset = 0;
            this._dimSize = dimSize;
            this._data = data;
        }

        mountMethods(this, data, source);
    }

    getSource(): Source {
        return this._source;
    }

    count(): number {
        return 0;
    }

    getItem(idx: number, out?: ArrayLike<number>): OptionDataItem {
        return;
    }

    appendData(newData: OptionSourceData): void {
    }

    clean(): void {
    }

    private static internalField = (function () {

        mountMethods = function (provider, data, source) {
            const sourceFormat = source.sourceFormat;
            const seriesLayoutBy = source.seriesLayoutBy;
            const startIndex = source.startIndex;
            const dimsDef = source.dimensionsDefine;

            const methods = providerMethods[getMethodMapKey(sourceFormat, seriesLayoutBy)];
            if (__DEV__) {
                assert(methods, 'Invalide sourceFormat: ' + sourceFormat);
            }

            extend(provider, methods);

            if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
                provider.getItem = getItemForTypedArray;
                provider.count = countForTypedArray;
                provider.fillStorage = fillStorageForTypedArray;
            }
            else {
                const rawItemGetter = getRawSourceItemGetter(sourceFormat, seriesLayoutBy);
                provider.getItem = bind(rawItemGetter, null, data, startIndex, dimsDef);
                const rawCounter = getRawSourceDataCounter(sourceFormat, seriesLayoutBy);
                provider.count = bind(rawCounter, null, data, startIndex, dimsDef);
            }
        };

        const getItemForTypedArray: DefaultDataProvider['getItem'] = function (
            this: DefaultDataProvider, idx: number, out: ArrayLike<number>
        ): ArrayLike<number> {
            idx = idx - this._offset;
            out = out || [];
            const data = this._data;
            const dimSize = this._dimSize;
            const offset = dimSize * idx;
            for (let i = 0; i < dimSize; i++) {
                out[i] = (data as ArrayLike<number>)[offset + i];
            }
            return out;
        };

        const fillStorageForTypedArray: DefaultDataProvider['fillStorage'] = function (
            this: DefaultDataProvider, start: number, end: number, storage: ArrayLike<ParsedValue>[], extent: number[][]
        ) {
            const data = this._data as ArrayLike<number>;
            const dimSize = this._dimSize;

            for (let dim = 0; dim < dimSize; dim++) {
                const dimExtent = extent[dim];
                let min = dimExtent[0] == null ? Infinity : dimExtent[0];
                let max = dimExtent[1] == null ? -Infinity : dimExtent[1];
                const count = end - start;
                const arr = storage[dim];
                for (let i = 0; i < count; i++) {
                    const val = data[(start + i) * dimSize + dim];
                    arr[start + i] = val;
                    val < min && (min = val);
                    val > max && (max = val);
                }
                dimExtent[0] = min;
                dimExtent[1] = max;
            }
        };

        const countForTypedArray: DefaultDataProvider['count'] = function (
            this: DefaultDataProvider
        ) {
            return this._data ? ((this._data as ArrayLike<number>).length / this._dimSize) : 0;
        };

        providerMethods = {

            [SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN]: {
                pure: true,
                appendData: appendDataSimply
            },

            [SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW]: {
                pure: true,
                appendData: function () {
                    throw new Error('Do not support appendData when set seriesLayoutBy: "row".');
                }
            },

            [SOURCE_FORMAT_OBJECT_ROWS]: {
                pure: true,
                appendData: appendDataSimply
            },

            [SOURCE_FORMAT_KEYED_COLUMNS]: {
                pure: true,
                appendData: function (this: DefaultDataProvider, newData: Dictionary<OptionDataValue[]>) {
                    const data = this._data as Dictionary<OptionDataValue[]>;
                    each(newData, function (newCol, key) {
                        const oldCol = data[key] || (data[key] = []);
                        for (let i = 0; i < (newCol || []).length; i++) {
                            oldCol.push(newCol[i]);
                        }
                    });
                }
            },

            [SOURCE_FORMAT_ORIGINAL]: {
                appendData: appendDataSimply
            },

            [SOURCE_FORMAT_TYPED_ARRAY]: {
                persistent: false,
                pure: true,
                appendData: function (this: DefaultDataProvider, newData: ArrayLike<number>): void {
                    if (__DEV__) {
                        assert(
                            isTypedArray(newData),
                            'Added data must be TypedArray if data in initialization is TypedArray'
                        );
                    }
                    this._data = newData;
                },

                // Clean self if data is already used.
                clean: function (this: DefaultDataProvider): void {
                    // PENDING
                    this._offset += this.count();
                    this._data = null;
                }
            }
        };

        function appendDataSimply(this: DefaultDataProvider, newData: ArrayLike<OptionDataItem>): void {
            for (let i = 0; i < newData.length; i++) {
                (this._data as any[]).push(newData[i]);
            }
        }

    })();
}



type RawSourceItemGetter = (
    rawData: OptionSourceData,
    startIndex: number,
    dimsDef: { name?: DimensionName }[],
    idx: number
) => OptionDataItem;

const getItemSimply: RawSourceItemGetter = function (
    rawData, startIndex, dimsDef, idx
): OptionDataItem {
    return (rawData as [])[idx];
};

const rawSourceItemGetterMap: Dictionary<RawSourceItemGetter> = {
    [SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN]: function (
        rawData, startIndex, dimsDef, idx
    ): OptionDataValue[] {
        return (rawData as OptionDataValue[][])[idx + startIndex];
    },
    [SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW]: function (
        rawData, startIndex, dimsDef, idx
    ): OptionDataValue[] {
        idx += startIndex;
        const item = [];
        const data = rawData as OptionDataValue[][];
        for (let i = 0; i < data.length; i++) {
            const row = data[i];
            item.push(row ? row[idx] : null);
        }
        return item;
    },
    [SOURCE_FORMAT_OBJECT_ROWS]: getItemSimply,
    [SOURCE_FORMAT_KEYED_COLUMNS]: function (
        rawData, startIndex, dimsDef, idx
    ): OptionDataValue[] {
        const item = [];
        for (let i = 0; i < dimsDef.length; i++) {
            const dimName = dimsDef[i].name;
            if (__DEV__) {
                if (dimName == null) {
                    throw new Error();
                }
            }
            const col = (rawData as Dictionary<OptionDataValue[]>)[dimName];
            item.push(col ? col[idx] : null);
        }
        return item;
    },
    [SOURCE_FORMAT_ORIGINAL]: getItemSimply
};

export function getRawSourceItemGetter(
    sourceFormat: SourceFormat, seriesLayoutBy: SeriesLayoutBy
): RawSourceItemGetter {
    const method = rawSourceItemGetterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];
    if (__DEV__) {
        assert(method, 'Do not suppport get item on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
    }
    return method;
}




type RawSourceDataCounter = (
    rawData: OptionSourceData,
    startIndex: number,
    dimsDef: { name?: DimensionName }[]
) => number;

const countSimply: RawSourceDataCounter = function (
    rawData, startIndex, dimsDef
) {
    return (rawData as []).length;
};

const rawSourceDataCounterMap: Dictionary<RawSourceDataCounter> = {
    [SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN]: function (
        rawData, startIndex, dimsDef
    ) {
        return Math.max(0, (rawData as OptionDataItem[][]).length - startIndex);
    },
    [SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW]: function (
        rawData, startIndex, dimsDef
    ) {
        const row = (rawData as OptionDataValue[][])[0];
        return row ? Math.max(0, row.length - startIndex) : 0;
    },
    [SOURCE_FORMAT_OBJECT_ROWS]: countSimply,
    [SOURCE_FORMAT_KEYED_COLUMNS]: function (
        rawData, startIndex, dimsDef
    ) {
        const dimName = dimsDef[0].name;
        if (__DEV__) {
            if (dimName == null) {
                throw new Error();
            }
        }
        const col = (rawData as Dictionary<OptionDataValue[]>)[dimName];
        return col ? col.length : 0;
    },
    [SOURCE_FORMAT_ORIGINAL]: countSimply
};

export function getRawSourceDataCounter(
    sourceFormat: SourceFormat, seriesLayoutBy: SeriesLayoutBy
): RawSourceDataCounter {
    const method = rawSourceDataCounterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];
    if (__DEV__) {
        assert(method, 'Do not suppport count on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
    }
    return method;
}



// TODO
// merge it to dataProvider?
type RawSourceValueGetter = (
    dataItem: OptionDataItem,
    dimIndex: DimensionIndex,
    dimName: DimensionName
    // If dimIndex is null/undefined, return OptionDataItem.
    // Otherwise, return OptionDataValue.
) => OptionDataValue | OptionDataItem;

const getRawValueSimply = function (
    dataItem: ArrayLike<OptionDataValue>, dimIndex: number, dimName: string
): OptionDataValue | ArrayLike<OptionDataValue> {
    return dimIndex != null ? dataItem[dimIndex] : dataItem;
};

const rawSourceValueGetterMap: {[sourceFormat: string]: RawSourceValueGetter} = {

    [SOURCE_FORMAT_ARRAY_ROWS]: getRawValueSimply,

    [SOURCE_FORMAT_OBJECT_ROWS]: function (
        dataItem: Dictionary<OptionDataValue>, dimIndex: number, dimName: string
    ): OptionDataValue | Dictionary<OptionDataValue> {
        return dimIndex != null ? dataItem[dimName] : dataItem;
    },

    [SOURCE_FORMAT_KEYED_COLUMNS]: getRawValueSimply,

    [SOURCE_FORMAT_ORIGINAL]: function (
        dataItem: OptionDataItem, dimIndex: number, dimName: string
    ): OptionDataValue | OptionDataItem {
        // FIXME: In some case (markpoint in geo (geo-map.html)),
        // dataItem is {coord: [...]}
        const value = getDataItemValue(dataItem);
        return (dimIndex == null || !(value instanceof Array))
            ? value
            : value[dimIndex];
    },

    [SOURCE_FORMAT_TYPED_ARRAY]: getRawValueSimply
};

export function getRawSourceValueGetter(sourceFormat: SourceFormat): RawSourceValueGetter {
    const method = rawSourceValueGetterMap[sourceFormat];
    if (__DEV__) {
        assert(method, 'Do not suppport get value on "' + sourceFormat + '".');
    }
    return method;
}


function getMethodMapKey(sourceFormat: SourceFormat, seriesLayoutBy: SeriesLayoutBy): string {
    return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS
        ? sourceFormat + '_' + seriesLayoutBy
        : sourceFormat;
}


// ??? FIXME can these logic be more neat: getRawValue, getRawDataItem,
// Consider persistent.
// Caution: why use raw value to display on label or tooltip?
// A reason is to avoid format. For example time value we do not know
// how to format is expected. More over, if stack is used, calculated
// value may be 0.91000000001, which have brings trouble to display.
// TODO: consider how to treat null/undefined/NaN when display?
export function retrieveRawValue(
    data: List, dataIndex: number, dim?: DimensionName | DimensionIndexLoose
    // If dimIndex is null/undefined, return OptionDataItem.
    // Otherwise, return OptionDataValue.
): OptionDataValue | OptionDataItem {
    if (!data) {
        return;
    }

    // Consider data may be not persistent.
    const dataItem = data.getRawDataItem(dataIndex);

    if (dataItem == null) {
        return;
    }

    const sourceFormat = data.getProvider().getSource().sourceFormat;
    let dimName;
    let dimIndex;

    const dimInfo = data.getDimensionInfo(dim);
    if (dimInfo) {
        dimName = dimInfo.name;
        dimIndex = dimInfo.index;
    }

    return getRawSourceValueGetter(sourceFormat)(dataItem, dimIndex, dimName);
}


/**
 * Compatible with some cases (in pie, map) like:
 * data: [{name: 'xx', value: 5, selected: true}, ...]
 * where only sourceFormat is 'original' and 'objectRows' supported.
 *
 * // TODO
 * Supported detail options in data item when using 'arrayRows'.
 *
 * @param data
 * @param dataIndex
 * @param attr like 'selected'
 */
export function retrieveRawAttr(data: List, dataIndex: number, attr: string): any {
    if (!data) {
        return;
    }

    const sourceFormat = data.getProvider().getSource().sourceFormat;

    if (sourceFormat !== SOURCE_FORMAT_ORIGINAL
        && sourceFormat !== SOURCE_FORMAT_OBJECT_ROWS
    ) {
        return;
    }

    let dataItem = data.getRawDataItem(dataIndex);
    if (sourceFormat === SOURCE_FORMAT_ORIGINAL && !isObject(dataItem)) {
        dataItem = null;
    }
    if (dataItem) {
        return (dataItem as Dictionary<OptionDataValue>)[attr];
    }
}
