"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var PublicApiCacheRepository_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PublicApiCacheRepository = void 0;
const const_1 = require("../../../../../../schema-definitions/vehicle-positions/redis/const");
const PublicApiCacheDtoSchema_1 = require("../../../../../../schema-definitions/vehicle-positions/redis/schemas/PublicApiCacheDtoSchema");
const RedisModel_1 = require("@golemio/core/dist/integration-engine/models/RedisModel");
const golemio_errors_1 = require("@golemio/core/dist/shared/golemio-errors");
const golemio_validator_1 = require("@golemio/core/dist/shared/golemio-validator");
const tsyringe_1 = require("@golemio/core/dist/shared/tsyringe");
const node_crypto_1 = require("node:crypto");
let PublicApiCacheRepository = PublicApiCacheRepository_1 = class PublicApiCacheRepository extends RedisModel_1.RedisModel {
    constructor() {
        super("PublicApiCacheRepository", {
            isKeyConstructedFromData: false,
            prefix: PublicApiCacheRepository_1.NAMESPACE_PREFIX,
        }, new golemio_validator_1.JSONSchemaValidator("PublicApiCacheRepository", PublicApiCacheDtoSchema_1.PublicApiCacheDtoSchema));
        this.CACHE_TTL = 1 * 60; // 1 minute
    }
    async geoadd(data, futureData, canceledData) {
        try {
            await this.validator.Validate(data);
        }
        catch (err) {
            throw new golemio_errors_1.GeneralError(`PublicApiCacheRepository: data validation failed: ${err.message}`, this.constructor.name, err);
        }
        const pipeline = this.connection.pipeline();
        try {
            const newSetKey = `${PublicApiCacheRepository_1.NAMESPACE_PREFIX}:${(0, node_crypto_1.randomBytes)(4).toString("hex")}`;
            for (const item of data) {
                // geo sorted set with vehicle ids (for quick lookup of vehicle ids in given area)
                pipeline.geoadd(newSetKey, item.lng, item.lat, item.vehicle_id);
                // list with vehicle ids for each trip (for quick lookup of vehicle ids for each trip)
                pipeline.rpush(`${newSetKey}:trip-${item.gtfs_trip_id}`, item.vehicle_id);
                pipeline.expire(`${newSetKey}:trip-${item.gtfs_trip_id}`, this.CACHE_TTL);
                // vehicle data for each vehicle id (for quick lookup of vehicle data for each vehicle id)
                pipeline.set(`${newSetKey}:vehicle-${item.vehicle_id}`, JSON.stringify(item), "EX", this.CACHE_TTL);
            }
            if (futureData.length > 0) {
                await this.geoaddFuture(futureData, newSetKey, pipeline);
            }
            if (canceledData.length > 0) {
                await this.geoaddCanceled(canceledData, newSetKey, pipeline);
            }
            pipeline.expire(newSetKey, this.CACHE_TTL);
            await pipeline.exec();
            return newSetKey;
        }
        catch (err) {
            pipeline.quit();
            if (err instanceof golemio_errors_1.AbstractGolemioError) {
                throw err;
            }
            throw new golemio_errors_1.GeneralError("PublicApiCacheRepository: geoadd failed", err);
        }
    }
    async geoaddFuture(futureData, newSetKey, pipeline) {
        try {
            await this.validator.Validate(futureData);
        }
        catch (err) {
            throw new golemio_errors_1.GeneralError(`PublicApiCacheRepository: future data validation failed: ${err.message}`, this.constructor.name, err);
        }
        try {
            for (const item of futureData) {
                // list with vehicle ids for future trips (for quick lookup of vehicle ids for each trip in the future)
                pipeline.rpush(`${newSetKey}:future-trip-${item.gtfs_trip_id}`, item.vehicle_id);
                pipeline.expire(`${newSetKey}:future-trip-${item.gtfs_trip_id}`, this.CACHE_TTL);
                // vehicle data for each vehicle id (for quick lookup of vehicle data for each vehicle id)
                pipeline.set(`${newSetKey}:future-vehicle-${item.vehicle_id}-${item.gtfs_trip_id}`, JSON.stringify(item), "EX", this.CACHE_TTL);
            }
        }
        catch (err) {
            throw new golemio_errors_1.GeneralError("PublicApiCacheRepository: geoaddFuture failed", err);
        }
    }
    async geoaddCanceled(canceledData, newSetKey, pipeline) {
        try {
            await this.validator.Validate(canceledData);
        }
        catch (err) {
            throw new golemio_errors_1.GeneralError(`PublicApiCacheRepository: future data validation failed: ${err.message}`, this.constructor.name, err);
        }
        try {
            for (const item of canceledData) {
                pipeline.set(`${newSetKey}:canceled-trips-${item.gtfs_trip_id}`, JSON.stringify(item), "EX", this.CACHE_TTL);
            }
        }
        catch (err) {
            throw new golemio_errors_1.GeneralError("PublicApiCacheRepository: geoaddCanceled failed", err);
        }
    }
};
exports.PublicApiCacheRepository = PublicApiCacheRepository;
PublicApiCacheRepository.NAMESPACE_PREFIX = const_1.PUBLIC_CACHE_NAMESPACE_PREFIX;
exports.PublicApiCacheRepository = PublicApiCacheRepository = PublicApiCacheRepository_1 = __decorate([
    (0, tsyringe_1.injectable)(),
    __metadata("design:paramtypes", [])
], PublicApiCacheRepository);
//# sourceMappingURL=PublicApiCacheRepository.js.map