"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 __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PropagateTrainDelayTask = void 0;
const BlockStopsRedisRepository_1 = require("../../../../ropid-gtfs/data-access/cache/BlockStopsRedisRepository");
const VPContainerToken_1 = require("../../../ioc/VPContainerToken");
const CoreToken_1 = require("@golemio/core/dist/helpers/ioc/CoreToken");
const sequelize_1 = require("@golemio/core/dist/shared/sequelize");
const tsyringe_1 = require("@golemio/core/dist/shared/tsyringe");
const PropagateTrainDelaySchema_1 = require("../schema/PropagateTrainDelaySchema");
const PositionsRepository_1 = require("../data-access/PositionsRepository");
const AbstractPropagateDelayTask_1 = require("./abstract/AbstractPropagateDelayTask");
let PropagateTrainDelayTask = class PropagateTrainDelayTask extends AbstractPropagateDelayTask_1.AbstractPropagateDelayTask {
    constructor(tripsRepository, positionsRepository, logger, blockStopsRepository, config) {
        super(tripsRepository, positionsRepository);
        this.blockStopsRepository = blockStopsRepository;
        this.queueName = "propagateTrainDelay";
        this.queueTtl = 5 * 60 * 1000; // 5 minutes
        this.schema = PropagateTrainDelaySchema_1.PropagateDelayValidationSchema;
        this.getNextGtfsTripId = async (gtfs_block_id, start_timestamp) => {
            const trip = await this.tripsRepository.findOne({
                attributes: ["gtfs_trip_id"],
                where: {
                    gtfs_block_id: gtfs_block_id,
                    start_timestamp: { [sequelize_1.Op.gt]: start_timestamp },
                },
                order: [["start_timestamp", "ASC"]],
                raw: true,
            });
            return trip?.gtfs_trip_id;
        };
        this.logger = logger;
        this.turnaroundEstimateInSeconds = config.getValue("module.pid.vehicle-positions.gtfsTripRun.turnaroundEstimateInSeconds", 0);
    }
    async execute(input) {
        for (const delayedPositions of input.data) {
            const { gtfs_trip_id, gtfs_block_id, vehicle_registration_number, start_timestamp, end_timestamp } = delayedPositions.trip;
            try {
                const nextGtfsTripId = await this.getNextGtfsTripId(gtfs_block_id, start_timestamp);
                if (!nextGtfsTripId) {
                    continue;
                }
                const blockedTrips = (await this.blockStopsRepository.get(gtfs_block_id));
                const lastStopCurrentTrip = blockedTrips[gtfs_trip_id]?.trip_stops?.at(-1)?.stop_id;
                const firstStopNextTrip = blockedTrips[nextGtfsTripId]?.trip_stops?.[0]?.stop_id;
                const requiredTurnaroundSeconds = lastStopCurrentTrip === firstStopNextTrip ? 0 : this.turnaroundEstimateInSeconds;
                await this.propagateDelayForGtfsTrip({
                    currentGtfsTripId: gtfs_trip_id,
                    currentGtfsBlockId: gtfs_block_id ?? null,
                    currentOriginTimestamp: delayedPositions.position.originTimestamp,
                    currentDelay: delayedPositions.position.delayInSeconds,
                    currentRegistrationNumber: vehicle_registration_number,
                    currentStartTime: start_timestamp,
                    currentEndTime: end_timestamp,
                    currentBearing: delayedPositions.position.bearing,
                    nextGtfsTrips: nextGtfsTripId
                        ? [
                            {
                                trip_id: nextGtfsTripId,
                                requiredTurnaroundSeconds: requiredTurnaroundSeconds,
                            },
                        ]
                        : [],
                    originPositionId: delayedPositions.position.originId,
                });
            }
            catch (err) {
                this.logger.warn(`${this.queueName}: could not propagate train delay for GTFS trip: ${gtfs_trip_id} - ${err.message}`);
            }
        }
    }
};
exports.PropagateTrainDelayTask = PropagateTrainDelayTask;
exports.PropagateTrainDelayTask = PropagateTrainDelayTask = __decorate([
    (0, tsyringe_1.injectable)(),
    __param(0, (0, tsyringe_1.inject)(VPContainerToken_1.VPContainerToken.TripRepository)),
    __param(1, (0, tsyringe_1.inject)(VPContainerToken_1.VPContainerToken.PositionsRepository)),
    __param(2, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.Logger)),
    __param(3, (0, tsyringe_1.inject)(VPContainerToken_1.VPContainerToken.BlockStopsRedisRepository)),
    __param(4, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.SimpleConfig)),
    __metadata("design:paramtypes", [Function, PositionsRepository_1.PositionsRepository, Object, BlockStopsRedisRepository_1.BlockStopsRedisRepository, Object])
], PropagateTrainDelayTask);
//# sourceMappingURL=PropagateTrainDelayTask.js.map