"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RegionService = void 0;
const async_lock_1 = __importDefault(require("async-lock"));
const region_1 = require("./region");
class RegionService {
    constructor(adapterOption) {
        this.adapterOption = adapterOption;
        this.allRegions = undefined;
        this.allRegionsLock = new async_lock_1.default();
    }
    getAllRegions(options) {
        return new Promise((resolve, reject) => {
            if (this.adapterOption.regions.length > 0) {
                resolve(this.adapterOption.regions);
            }
            else if (this.allRegions && this.allRegions.length > 0) {
                resolve(this.allRegions);
            }
            else {
                this.allRegionsLock.acquire('all', () => {
                    if (this.allRegions && this.allRegions.length > 0) {
                        return Promise.resolve(this.allRegions);
                    }
                    return region_1.Region.getAll({
                        accessKey: this.adapterOption.accessKey,
                        secretKey: this.adapterOption.secretKey,
                        ucUrl: this.adapterOption.ucUrl,
                        timeout: options === null || options === void 0 ? void 0 : options.timeout,
                        retry: options === null || options === void 0 ? void 0 : options.retry,
                        retryDelay: options === null || options === void 0 ? void 0 : options.retryDelay,
                        appName: this.adapterOption.appName,
                        appVersion: this.adapterOption.appVersion,
                        uplogBufferSize: this.adapterOption.uplogBufferSize,
                        requestCallback: this.adapterOption.requestCallback,
                        responseCallback: this.adapterOption.responseCallback,
                        stats: options === null || options === void 0 ? void 0 : options.stats,
                    });
                }).then((regions) => {
                    this.allRegions = regions;
                    resolve(regions);
                }).catch(reject);
            }
        });
    }
    clearCache() {
        this.allRegions = undefined;
    }
    getS3Endpoint(s3RegionId, options) {
        return new Promise((resolve, reject) => {
            let queryCondition;
            if (s3RegionId) {
                queryCondition = (region) => region.s3Id === s3RegionId && region.s3Urls.length > 0;
            }
            else {
                queryCondition = (region) => !!region.s3Id && region.s3Urls.length > 0;
            }
            const queryInRegions = (regions) => {
                const region = regions.find(queryCondition);
                if (region) {
                    resolve({ s3Id: region.s3Id, s3Endpoint: region.s3Urls[0] });
                }
                else if (s3RegionId) {
                    reject(new Error(`Cannot find region endpoint url of ${s3RegionId}`));
                }
                else {
                    reject(new Error(`Cannot find valid region endpoint url`));
                }
            };
            this.getAllRegions(options).then(queryInRegions).catch(reject);
        });
    }
    fromKodoRegionIdToS3Id(regionId, options) {
        return new Promise((resolve, reject) => {
            const queryCondition = (region) => region.id === regionId;
            const queryInRegions = (regions) => {
                const region = regions.find(queryCondition);
                if (region && region.s3Id) {
                    resolve(region.s3Id);
                }
                else {
                    reject(new Error(`Cannot find region s3 id of ${regionId}`));
                }
            };
            this.getAllRegions(options).then(queryInRegions).catch(reject);
        });
    }
    fromS3IdToKodoRegionId(s3Id, options) {
        return new Promise((resolve, reject) => {
            const queryCondition = (region) => region.s3Id === s3Id;
            const queryInRegions = (regions) => {
                const region = regions.find(queryCondition);
                if (region && region.id) {
                    resolve(region.id);
                }
                else {
                    reject(new Error(`Cannot find region id of ${s3Id}`));
                }
            };
            this.getAllRegions(options).then(queryInRegions).catch(reject);
        });
    }
}
exports.RegionService = RegionService;
//# sourceMappingURL=region_service.js.map