"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SourceTokenScraper = void 0;
const error_1 = require("../../../error");
const functional_1 = require("../../../functional");
const logger_1 = require("../../../logger");
class SourceTokenScraper {
    constructor(validDurationMs = 1500000) {
        this.tokenValidDurationMs = validDurationMs;
        this.promise = new Promise((resolve) => (this.resolve = resolve));
        this.fetchState = "NONE";
    }
    async getToken() {
        if (this.fetchState === "NONE") {
            this.fetchState = "FETCHING";
            return undefined;
        }
        else if (this.fetchState === "FETCHING") {
            return this.promise;
        }
        else if (this.fetchState === "VALID") {
            if (this.isTokenExpired()) {
                this.fetchState = "FETCHING";
                this.promise = new Promise((resolve) => (this.resolve = resolve));
                return undefined;
            }
            return this.promise;
        }
        else {
            (0, functional_1.assertExhaustive)(this.fetchState);
        }
    }
    isTokenExpired() {
        if (this.expiry === undefined) {
            throw new error_1.FirebaseError("Your deployment is checking the expiration of a source token that has not yet been polled. " +
                "Hitting this case should never happen and should be considered a bug. " +
                "Please file an issue at https://github.com/firebase/firebase-tools/issues " +
                "and try deploying your functions again.");
        }
        return Date.now() >= this.expiry;
    }
    get poller() {
        return (op) => {
            var _a, _b, _c, _d, _e;
            if (((_a = op.metadata) === null || _a === void 0 ? void 0 : _a.sourceToken) || op.done) {
                const [, , , region] = ((_c = (_b = op.metadata) === null || _b === void 0 ? void 0 : _b.target) === null || _c === void 0 ? void 0 : _c.split("/")) || [];
                logger_1.logger.debug(`Got source token ${(_d = op.metadata) === null || _d === void 0 ? void 0 : _d.sourceToken} for region ${region}`);
                this.resolve((_e = op.metadata) === null || _e === void 0 ? void 0 : _e.sourceToken);
                this.fetchState = "VALID";
                this.expiry = Date.now() + this.tokenValidDurationMs;
            }
        };
    }
}
exports.SourceTokenScraper = SourceTokenScraper;