"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UpdateNotificationManager = void 0;
const semver_1 = __importDefault(require("semver"));
const fs_1 = require("fs");
class UpdateNotificationManager {
    constructor({ fetch, }) {
        this.latestKnownMongoshVersion = undefined;
        this.currentVersionGreetingCTA = undefined;
        this.localFilesystemFetchInProgress = undefined;
        this.fetch = fetch;
    }
    async getLatestVersionIfMoreRecent(currentVersion) {
        try {
            await this.localFilesystemFetchInProgress;
        }
        catch {
        }
        if (!this.latestKnownMongoshVersion)
            return null;
        if (currentVersion &&
            !semver_1.default.gt(this.latestKnownMongoshVersion, currentVersion))
            return null;
        if (currentVersion && semver_1.default.prerelease(currentVersion))
            return null;
        return this.latestKnownMongoshVersion;
    }
    async getGreetingCTAForCurrentVersion() {
        try {
            await this.localFilesystemFetchInProgress;
        }
        catch {
        }
        return this.currentVersionGreetingCTA?.chunks;
    }
    async fetchUpdateMetadata(updateURL, localFilePath, currentVersion) {
        let localFileContents;
        await (this.localFilesystemFetchInProgress = (async () => {
            let localFileText = '';
            try {
                localFileText = await fs_1.promises.readFile(localFilePath, 'utf-8');
            }
            catch (err) {
                if (!(err &&
                    typeof err === 'object' &&
                    'code' in err &&
                    err.code === 'ENOENT'))
                    throw err;
            }
            try {
                localFileContents = JSON.parse(localFileText);
            }
            catch {
            }
            if (localFileContents?.updateURL !== updateURL) {
                localFileContents = undefined;
            }
            if (localFileContents?.latestKnownMongoshVersion) {
                this.latestKnownMongoshVersion =
                    localFileContents.latestKnownMongoshVersion;
            }
            if (localFileContents?.cta && currentVersion in localFileContents.cta) {
                this.currentVersionGreetingCTA = localFileContents.cta[currentVersion];
            }
            this.localFilesystemFetchInProgress = undefined;
        })());
        if (localFileContents?.lastChecked &&
            Date.now() - localFileContents.lastChecked < 86400_000) {
            return;
        }
        const response = await this.fetch(updateURL, {
            headers: localFileContents?.etag
                ? { 'if-none-match': localFileContents?.etag }
                : {},
        });
        if (response.status === 304) {
            response.body
                ?.once('error', () => {
            })
                .resume();
            localFileContents = { ...localFileContents, lastChecked: Date.now() };
            await fs_1.promises.writeFile(localFilePath, JSON.stringify(localFileContents));
            return;
        }
        if (!response.ok || !response.body) {
            throw new Error(`Unexpected status code fetching ${updateURL}: ${response.status} ${response.statusText}`);
        }
        const jsonContents = (await response.json());
        this.latestKnownMongoshVersion = jsonContents?.versions
            ?.map((v) => v.version)
            ?.filter((v) => !semver_1.default.prerelease(v))
            ?.sort(semver_1.default.rcompare)?.[0];
        this.currentVersionGreetingCTA =
            jsonContents?.versions?.find((v) => v.version === currentVersion)?.cta ??
                jsonContents?.cta;
        const latestKnownVersionCTA = jsonContents?.versions?.find((v) => v.version === this.latestKnownMongoshVersion)?.cta ?? jsonContents?.cta;
        localFileContents = {
            updateURL,
            lastChecked: Date.now(),
            etag: response.headers.get('etag') ?? undefined,
            latestKnownMongoshVersion: this.latestKnownMongoshVersion,
            cta: {
                [currentVersion]: this.currentVersionGreetingCTA,
                ...(this.latestKnownMongoshVersion &&
                    this.latestKnownMongoshVersion !== currentVersion && {
                    [this.latestKnownMongoshVersion]: latestKnownVersionCTA,
                }),
            },
        };
        await fs_1.promises.writeFile(localFilePath, JSON.stringify(localFileContents));
    }
}
exports.UpdateNotificationManager = UpdateNotificationManager;
//# sourceMappingURL=update-notification-manager.js.map