import {backend_config} from './interface/interface';
import {GLOBAL_BACKEND} from './global';
import {ppl_debug} from './include/log'
//const fs = require('fs');

export default class Executer{
    protected modeConfig_:backend_config = <any>{};
    ret: number = 0;
    constructor(config:backend_config){
        this.modeConfig_= config;
        if (!GLOBAL_BACKEND.backendInstance) {
            console.error('no backend instance has been registered!');
            this.ret = -1;
        }
        ppl_debug(this.modeConfig_.debug!,"backend engin is ",GLOBAL_BACKEND.backend);
        //use model data to build a graph
        GLOBAL_BACKEND.backendInstance.createGraph(this.modeConfig_);
    }

    async prepare(){
        if(this.ret !=0) return this.ret;
        return await GLOBAL_BACKEND.backendInstance.prepare();
    }

    forward(ifGetOutput:boolean = false):any|Promise<ArrayBuffer[]>{
        return GLOBAL_BACKEND.backendInstance.forward(ifGetOutput);
    }

    release(){ GLOBAL_BACKEND.backendInstance.release();}

    setInputByArrayBuffer(data : ArrayBuffer[]):number{
        return GLOBAL_BACKEND.backendInstance.setInputByArrayBuffer(data);
    }

    //give one or more number[]/array to initialize input of network
    setInputByArray(data : any[]|Array<any>):number
    {
        var tmpData:ArrayBuffer[] = new Array(0);
        for(let i of data){
            let tmpBuffer = new Float32Array(i).buffer;
            tmpData.push(tmpBuffer);
        }
        var res:number = this.setInputByArrayBuffer(tmpData);
        return res;
    }

    //set input:the number of input depends on the numbers of net input 
    //give one or more file path names of input data to the network 
    setInputByPath(firstName :string,...restName :string[]):number{
        const dataArray: any[] = [];
        //due to we can't use fs in browser,we delete the fs temporaryly
        /* fs.readFile(firstName, "utf8",function (err, data) {
            if (err) {
                return console.error(err);
            }
            dataArray.push(data);
        });
        for(let i of restName){
            fs.readFile(i, "utf8",function (err, data) {
                if (err) {
                    return console.error(err);
                }
                dataArray.push(data);
            });
        }
        if(dataArray==null){
            console.error("read data by path failed ");
            return -1;
        } */
        return this.setInputByArray(dataArray);
    }
    
    getArrayBufferOutput():Promise<ArrayBuffer[]>{
        return GLOBAL_BACKEND.backendInstance.getArrayBufferOutput();
    }

    getInputShapeByIndex(idx:number):any{
        return GLOBAL_BACKEND.backendInstance.getInputShapeByIndex(idx);
    }

    getOutputShapeByIndex(idx:number):any{
        return GLOBAL_BACKEND.backendInstance.getOutputShapeByIndex(idx);
    }

    getInputCount():number{
        return GLOBAL_BACKEND.backendInstance.getInputCount();
    }

    getOutputCount():number{
        return GLOBAL_BACKEND.backendInstance.getOutputCount();
    }

    //can be used for synchronization
    finishWork():Promise<undefined[]>{
        return GLOBAL_BACKEND.backendInstance.finishWork();
    }
    
}