import Buffer from './buffer'
import {tensorInfo} from './interface/interface'

 export default abstract class Tensor {
    //tensorInfo which includes name/shape/precision/data
    private tensorInfo_: tensorInfo;
    private producerCount_:number ;
    private consumerCount_:number ;
    
    constructor(t:tensorInfo) {
        this.tensorInfo_ = t;
        this.producerCount_ = 0;
        this.consumerCount_ = 0;
    }
    public dimCount():number {return this.tensorInfo_.shape.length;}
    public dim(index:number):number {return this.tensorInfo_.shape[index];}
    public shape():number[] {return this.tensorInfo_.shape;}
    public byteLength():number {
        var shapeNum_:number[] = this.shape();
        return shapeNum_[0]*shapeNum_[1]*shapeNum_[2]*shapeNum_[3]*(this.precision()+1)*2;
    }

    //create the real memory according bufferinfo
    //each backend should have it's way to malloc buffer.
    abstract mallocTensorBuffer():number;
    abstract releaseTensorBuffer():number;
    abstract data():any;

    public precision():number {return this.tensorInfo_.precision;}
    
    public get name():string { return this.tensorInfo_.name;}
    public set name(name_:string) { this.tensorInfo_.name = name_;}
    public get buffer():Buffer { return this.tensorInfo_.deviceData!;}
    public set buffer(buffer_:Buffer){ this.tensorInfo_.deviceData=buffer_;}
    
    public getname():string { return this.tensorInfo_.name;}
    public setname(name_:string) { this.tensorInfo_.name = name_;}
    public getbuffer():Buffer { return this.tensorInfo_.deviceData!;}
    public setbuffer(buffer_:Buffer){ this.tensorInfo_.deviceData=buffer_;}
    
    public producerCount():number { return this.producerCount_;}
    public consumerCount():number { return this.consumerCount_;}
    public incProducerCount():void { this.producerCount_++;}
    public incConsumerCount():void { this.consumerCount_++;}
};