"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DistributedActorLock = void 0;
const base_1 = require("@darlean/base");
/**
 * Implementation of {@link IActorLock} that uses the distributed actor lock provided in {@link @darlean/actor-lock-suite}.
 */
class DistributedActorLock {
    constructor(time, service, appId) {
        this.time = time;
        this.service = service;
        this.appId = appId;
    }
    async acquire(id, onBroken) {
        // const now = this.time.machineTicks();
        const result = await this.service.acquire({
            id,
            requester: this.appId,
            ttl: 60 * 1000,
            singleStage: true
        });
        // TODO: Better checks on result.duration, use remaining duration to determine when to check next time
        if (result.duration > 0) {
            // let until = now + result.duration;
            const refreshTimer = this.time.repeat(async () => {
                // console.log('REFRESH ACTOR LOCK', id);
                // const refreshNow = this.time.machineTicks();
                try {
                    const refreshResult = await this.service.acquire({
                        id,
                        requester: this.appId,
                        ttl: 60 * 1000,
                        singleStage: true
                    });
                    if (refreshResult.duration > 0) {
                        // until = refreshNow + refreshResult.duration;
                    }
                    else {
                        onBroken();
                    }
                }
                catch (e) {
                    console.log('ERROR DURING REFRESH ACTOR LOCK', e);
                    onBroken();
                }
            }, 'ActorLockRefresh ' + JSON.stringify(id), 30 * 1000);
            return {
                release: async () => {
                    await refreshTimer.cancel();
                    await this.service.release({
                        id,
                        requester: this.appId
                    });
                }
            };
        }
        else {
            throw new base_1.FrameworkError(base_1.FRAMEWORK_ERROR_ACTOR_LOCK_FAILED, `It was not possible to acquire the actor lock for [Id] by [AppId]. It is likely hold by one of [${base_1.FRAMEWORK_ERROR_PARAMETER_REDIRECT_DESTINATION}].`, { [base_1.FRAMEWORK_ERROR_PARAMETER_REDIRECT_DESTINATION]: result.holders, Id: id, AppId: this.appId });
        }
    }
}
exports.DistributedActorLock = DistributedActorLock;
