/**
 * 
 */
export class Deferred<T = any> {
    private _promise: Promise<T> = null!;
    private _resolve: (value: T | PromiseLike<T>) => void = null!;
    private _reject: (reason?: any) => void = null!;
    constructor() {
        let self = this;
        self._promise = new Promise((resolve, reject) => {
            self._resolve = resolve;
            self._reject = reject;
        });
    }

    get promise(): Promise<T> { return this._promise; }
    resolve(value?: T) {
        if (this._resolve) {
            this._resolve.call(this._promise, value);
            this._resolve = null;
        }
    }
    reject(reason?: any) {
        if (this._reject) {
            this._reject.call(this._promise, reason);
            this._reject = null;
        }
    }
}

/**
 * 执行 n 次 resolve 后才执行真正的 resolve
 * 允许在执行前动态的添加执行次数
 */
export class NDeferred<T = any> {
    private _promise: Promise<T> = null!;
    private _resolve: (value: T | PromiseLike<T>) => void = null!;
    private _reject: (reason?: any) => void = null!;
    private m_Cnt: number = 0;
    static Create<TT>(cnt: number): NDeferred<TT> { return new NDeferred<TT>(cnt); }
    private constructor(cnt: number) {
        const that = this;
        if (cnt <= 0) {
            throw "[NDeferred] 执行次数必须大于 0";
        }
        that.m_Cnt = cnt;
        that._promise = new Promise((resolve, reject) => {
            that._resolve = (p: T) => {
                if (that.m_Cnt <= 0) {
                    return;
                };
                --that.m_Cnt;
                if (that.m_Cnt === 0) {
                    resolve(p)
                }
            };
            that._reject = reject;
        });
    }

    /**
     * 动态增加执行所需次数
     */
    add() {
        const that = this;
        if (that.m_Cnt > 0) {
            ++that.m_Cnt;
        } else {
            throw "[NDeferred] 执行次数等于 0，表明 promise 已 resolve，不能再动态添加执行次数";
        }
    }

    addCnt(cnt: number) {
        const that = this;
        if (that.m_Cnt > 0) {
            that.m_Cnt += cnt;
        } else {
            throw "[NDeferred] 执行次数等于 0，表明 promise 已 resolve，不能再动态添加执行次数";
        }
    }

    get promise(): Promise<T> { return this._promise; }
    resolve(value?: T) { this._resolve.call(this._promise, value); }
    reject(reason?: any) { this._reject.call(this._promise, reason); }
}
