import { AstHelper, PrintSdk } from "@gvol-org/geovis-brain-core";
import { Feature } from "../models/Feature";
import { PrintObject } from "../models/PrintObject";
import { Number } from "../dataType/Number";
import { Boolean } from "../dataType/Boolean";
import { Filter } from "../models/Filter";
import { Array } from "../dataType/Array";
import { Geometry } from "../models/Geometry";
import { String } from "../dataType/String";
import { Reducer } from "../models/Reducer";
// import { AstHelper } from "../common/AstHelper";

export class TP0 {

}
/**
 * @class gve.List
 * @since gve
 */
export class List<T> extends PrintObject {


   /**
     *  List的构造方法,构造一个新List
     * @hideconstructor
     * @param {List<Object> | Object} [items] 一个列表或一个计算对象
     * @returns gve.List
   */
    constructor(items?: List<Object> | Object) {
        super();

    }

    /**
     *  将other的连接到列表中
     *  @param {List} other List对象
     *  @return List
     */
    cat(other: List<T>): List<T> {
        // this.push()
        return new List();
    }

    /**
     *  列表拉平
     *  @return List
     */
    flatten(): List<T> {
        return new List();
    }

    /**
     *  返回开始索引和结束索引之间的列表部分
     *  @param {number} start List对象
     *  @param {number} end List对象
     *  @param {number} [step] List对象
     *  @return List
     */
    slice(start: number, end: number, step?: number): List<T> {
        return new List();
    }

    /**
     *  将元素追加到列表的末尾。
     *  @param {object} element List对象
     *  @return List
     */
    add(element: object): List<T> {
        return new List();
    }

    /**
     *  通过index获取list中元素
     *  @param {number} index 索引
     *  @return object
     */
    get(index: number) {
        return new PrintObject();
    }
    /**
      *  生成从开始到结束(包括)的数字序列,以步长为增量,或以等距的计数增量。如果未指定end,则从start +step*count开始计算,因此必须指定end或count中的至少一个。
      *  @param {number} [start] 开始 
      *  @param {number} [end] 结束
      *  @param {number} [step] 步长
      *  @param {number} [count] 计数
      *  @return List
      *  @tutorial gve.List
      * 
      */
    static sequence(start: number, end?: number | Number, step?: number | Number, count?: number): List<number> {
        return new List()
    }

    /**
     *   将算法映射到列表上,针对List中的每个元素进行循环计算。
     *    @param {Function} algorithm 参数是List的方法,需要返回List。
     *   @return List
     */
    map(algorithm: Function): List<T> {

        var fe = new PrintObject();
        // (fe as any).expressions = "fe";
        (fe as any).tag = "orgObject";

        //先存一下当前的publicChain和publicIndex,等执行完恢复
        let oldChain = [...AstHelper.publicChain];
        let oldIndex = AstHelper.publicIndex;
        let oldBlockNo = AstHelper.blockNo;
        //将当前层级之前的调用链存放在allChain的最后,当执行完当前层级后删掉
        // let publicChainLength = AstHelper.publicChain.length;
        // AstHelper.allChain.push(...AstHelper.publicChain);
        let mapChain: any[] = [];
        let mapIndex: number = 0;
        AstHelper.publicChain = mapChain;
        AstHelper.publicIndex = mapIndex;
        AstHelper.blockNo = AstHelper.mapBlockNo + 1;
        AstHelper.mapBlockNo++;
        let orgObjectKey = "".padStart(AstHelper.blockNo, '$') + "orgObject";
        var res = algorithm.call(this, fe);
        res["chain"] = AstHelper.relativeChain(res.order);
        AstHelper.publicChain = oldChain;
        AstHelper.publicIndex = oldIndex;
        AstHelper.blockNo = oldBlockNo;
        // AstHelper.allChain = AstHelper.allChain.slice(0, AstHelper.allChain.length - publicChainLength);

        var resExp = AstHelper.stringify(res)
        // console.log("callmap", res, (res as any).expressions, resExp);
        var collection = new List();
        // (collection as any).expressions = "function (fe){return " + resExp + "}";
        if (res.reference) {
            collection["reference"] = res.reference;
            collection["chain"] = res.chain;
            collection["order"] = res.order;
            collection["orgObjectKey"] = orgObjectKey;
            algorithm["reference"] = res.reference;
        }

        return collection;
    }

    /**
     *  替换List中的某一位置的元素
     *  @param {number} index 索引
     *  @param {any} element 替换元素
     *  @return List<any>
     */
    set(index: number, element: any) {
        return new List<any>();
    }

    /**
     *  获取List中元素的个数
     *  @return number
     */
    size() {
        return new Number();
    }

    /**
     *  判断List中是否包含某一元素
     *  @param {any} element 元素
     *  @return boolean
     */
    contains(element: any) {
        return new Boolean();
    }

    /**
     *  判断List1与List2是否拥有相同的元素
     *  @param {List<any>} list list数组
     *  @return boolean
     */
    equals(list: List<any> | any[]) {
        return new Boolean();
    }

    /**
     *  获取List长度
     *  @return number
     */
    length() {
        return new Number();
    }

    /**
     *  移除List中的某个元素
     *  @param {any} element 元素
     *  @return List<any>
     */
    remove(element: any) {
        return new List<any>();
    }

    /**
     *  List中的某个位置插入某个元素
     *  @param {number} index 索引
     *  @param {any} element 插入元素
     *  @return List<any>
     */
    insert(index: number, element: any) {
        return new List<any>();
    }

    /**
     *  List 某个元素出现多次的新List
     *  @param {any} value 插入元素
     *  @param {number} count 次数
     *  @return List<any>
     *  @tutorial gve.List
     */
    static repeat(value: any, count: number) {
        return new List<any>();
    }

    /**
     *  List 用第二个参数替换第一个参数的值
     *  @param {any} oldval 被替换的值
     *  @param {any} newval 替换值
     *  @return List<any>
     */
    replace(oldval: any, newval: any) {
        return new List<any>();
    }

    /**
     *  List 逆序
     *  @return List<any>
     */
    reverse() {
        return new List<any>();
    }

    /**
     *  List 交换两个位置的元素
     *  @param {number} pos1 元素位置索引
     *  @param {number} pos2 元素位置索引
     *  @return List<any>
     */
    swap(pos1: number, pos2: number) {
        return new List<any>();
    }

    /**
     *  是否包含另外一个列表的所有元素
     *  @param {List<any>} other List实例
     *  @return Boolean
     */
    containsAll(other: List<any>) {
        return new Boolean();
    }

    /**
     *  返回去除重复元素的列表
     *  @return List<any>
     */
    distinct() {
        return new List<any>();
    }

    /**
     *  根据指定的过滤器过滤元素
     *  @param {Filter} filter Filter过滤器实例
     *  @return List<any>
     */
    filter(filter: Filter) {
        return new List<any>();
    }

    /**
     *  返回列表中某个值的数量
     *  @param {any} element Object对象
     *  @return Number
     */
    frequency(element: any) {
        return new Number();
    }

    /**
     *  返回列表中指定位置的数组
     *  @param {number} index 索引
     *  @return Array
     */
    getArray(index: number) {
        return new Array();
    }

    /**
     *  返回列表中指定位置的geometry
     *  @param {number} index 索引
     *  @return Geometry
     */
    getGeometry(index: number) {
        return new Geometry();
    }

    /**
     *  返回列表中指定位置的字符串 
     *  @param {number} index 索引
     *  @return String
     */
    getString(index: number) {
        return new String();
    }

    /**
     *  返回某元素在列表中出现的第一个位置
     *  @param {any} element Object对象
     *  @return Number
     */
    indexOf(element: any) {
        return new Number();
    }

    /**
     *  返回列表中出现和目标序列的第一个同样序列的位置
     *  @param {List<any>} target List实例
     *  @return Number
     */
    indexOfSublist(target: List<any>) {
        return new Number();
    }

    /**
     *  用指定的字符串符合连接列表并返回连接后的字符串
     *  @param {string} separator 字符串
     *  @return String
     */
    join(separator: string) {
        return new String();
    }

    /**
     *  使用reducer操作
     *  @param {Reducer} reducer Reducer实例
     *  @return Object
     */
    reduce(reducer: Reducer) {
        return new PrintObject();
    }

    /**
     *  从列表中移除掉包含在other的值
     *  @param {List<any>} other List实例
     *  @return List<any>
     */
    removeAll(other: List<any>) {
        return new List<any>();
    }

    /**
     *  将列表中所有的oldval替换为newval
     *  @param {any} oldval 被替换的值
     *  @param {any} newval 替换值
     *  @return List<any>
     */
    replaceAll(oldval: any, newval: any) {
        return new List<any>();
    }

    /**
     *  将list移动distance个位置 
     *  @param {number} distance 移动位置数值
     *  @return List<any>
     */
    rotate(distance: number) {
        return new List<any>();
    }

    /**
     *  序列化成json字符串 
     *  @param {boolean} [legacy] 可选参数,参数序列化结果是否使用原数据格式 
     *  @return String
     */
    serialize(legacy?: boolean) {
        return new String();
    }

    /**
     *  随机排列列表 
     *  @param {any} seed 默认为null
     *  @return List<any>
     */
    shuffle(seed: any = null) {
        return new List<any>();
    }

    /**
     *  根据升序对列表进行排序 
     *  @param {List<any>} keys List实例,默认为null
     *  @return List<any>
     */
    sort(keys: List<any> = null) {
        return new List<any>();
    }

    /**
     *  从start开始,移除count个元素,并将other的内容插入到这个位置 
     *  @param {number} start 开始位置 
     *  @param {number} count 移除元素个数 
     *  @param {List<any>} other 新插入内容List,默认为null
     *  @return List<any>
     */
    splice(start: number, count: number, other: List<any>) {
        return new List<any>();
    }

    /**
     *  将内部列表中的第一个元素放到第一个列表中,将第二个元素放到第二个列表中,依次类推,和zip是相反操作 
     *  @return List<any>
     */
    unzip() {
        return new List();
    }

    /**
     *  将两个列表转换为一个列表,返回新列表 
     *  @param {List<any>} other 待合并列表
     *  @return List<any>
     */
    zip(other: List<any>) {
        return new List();
    }

    /**
     *  返回列表中出现和目标序列的最后一个同样序列的位置
     *  @param {List<any>} target 目标列表
     *  @return Number
     */
    lastIndexOfSubList(target: List<any>) {
        return new Number();
    }

    /**
     *  返回列表中指定位置的数字
     *  @param {number} index 索引
     *  @return Number
     */
    getNumber(index: number) {
        return new Number();
    }

    // /**
    //  *  异步从服务器检索该对象的值并将其传递给提供的回调函数
    //  *  @param {Function} callback 回调函数
    //  */
    evaluate(callback: Function) {
        PrintSdk.evaluate(this).then((data) => {
            callback(data);
        });
        return this;
    }
}