"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.DeparturesRepository = void 0;
const const_1 = require("../../../schema-definitions/const");
const CoreToken_1 = require("@golemio/core/dist/helpers/ioc/CoreToken");
const golemio_errors_1 = require("@golemio/core/dist/shared/golemio-errors");
const sequelize_1 = require("@golemio/core/dist/shared/sequelize");
const tsyringe_1 = require("@golemio/core/dist/shared/tsyringe");
const DepartureMode_1 = require("../helpers/enums/DepartureMode");
const ONE_MINUTE_IN_MILLIS = 60000;
let DeparturesRepository = class DeparturesRepository {
    constructor(connector, config) {
        this.connector = connector;
        this.schema = const_1.PG_SCHEMA;
        this.isAirConditioningFeatureEnabled = config.getBoolean("module.pid.vehicle-positions.isAirCondEnabled", true);
    }
    GetOne(id) {
        throw new Error("Method not implemented.");
    }
    /** Retrieves all departures
     *
     * @param {IDeparturesViewOptions} options - All query options
     * @returns {Promise<IPIDDeparture[]>} Array of the retrieved records
     */
    async GetAll(options) {
        const { start, end, canceledStart, canceledEnd } = this.getDepartureTimestamps(options);
        const result = await this.connector.getConnection().query(`
            SELECT * from ${this.schema}.get_departures(
                $stopsids,
                $mode,
                $datedeparturebetweenstart,
                $datedeparturebetweenend,
                $isnegativeminutesbefore,
                $datecanceleddeparturebetweenstart,
                $datecanceleddeparturebetweenend,
                $airconditioninfoenabled);`, {
            type: sequelize_1.QueryTypes.SELECT,
            bind: {
                stopsids: options.stopsIds.join(","),
                mode: options.mode === DepartureMode_1.DepartureMode.ARRIVALS ? 2 : options.mode === DepartureMode_1.DepartureMode.MIXED ? 3 : 1,
                datedeparturebetweenstart: start,
                datedeparturebetweenend: end,
                isnegativeminutesbefore: options.minutesBefore < 0 ? 1 : 0,
                datecanceleddeparturebetweenstart: canceledStart,
                datecanceleddeparturebetweenend: canceledEnd,
                airconditioninfoenabled: this.isAirConditioningFeatureEnabled && options.isAirCondition ? 1 : 0,
            },
        });
        return result;
    }
    /** Retrieves transfer departures
     *
     * @param {ITransfersViewOptions} options - All query options
     * @returns {Promise<ITransferDeparture[]>} Array of the retrieved records
     */
    async getTransferDepartures(options) {
        // Always fall back to 0 minutes before and 60 minutes after
        const minutesBefore = 0;
        const minutesAfter = 60;
        const { start, end, canceledStart, canceledEnd } = this.getDepartureTimestamps({
            currentMoment: options.currentMoment,
            minutesOffset: options.minutesOffset,
            minutesBefore,
            minutesAfter,
        });
        try {
            return await this.connector.getConnection().query(`
                select * from ${this.schema}.get_transfers(
                    $stopsids,
                    $datedeparturebetweenstart,
                    $datedeparturebetweenend,
                    $datecanceleddeparturebetweenstart,
                    $datecanceleddeparturebetweenend);`, {
                type: sequelize_1.QueryTypes.SELECT,
                bind: {
                    stopsids: options.stopsIds.join(","),
                    datedeparturebetweenstart: start,
                    datedeparturebetweenend: end,
                    datecanceleddeparturebetweenstart: canceledStart,
                    datecanceleddeparturebetweenend: canceledEnd,
                },
            });
        }
        catch (error) {
            throw new golemio_errors_1.GeneralError("Failed to retrieve transfer departures", this.constructor.name, error, 500);
        }
    }
    getDepartureTimestamps(options) {
        const currentTime = options.currentMoment.valueOf(); // in milliseconds
        // Calculate base timestamps
        const baseStart = currentTime + (options.minutesOffset - options.minutesBefore) * ONE_MINUTE_IN_MILLIS;
        const baseEnd = currentTime + (options.minutesOffset + options.minutesAfter) * ONE_MINUTE_IN_MILLIS;
        // Calculate canceled timestamps
        const canceledBaseStart = currentTime + (options.minutesOffset - 3) * ONE_MINUTE_IN_MILLIS;
        const canceledBaseEnd = currentTime + (options.minutesOffset + 3) * ONE_MINUTE_IN_MILLIS;
        return {
            start: new Date(baseStart),
            end: new Date(baseEnd),
            canceledStart: new Date(Math.min(baseStart, canceledBaseStart)),
            canceledEnd: new Date(Math.max(baseEnd, canceledBaseEnd)),
        };
    }
};
exports.DeparturesRepository = DeparturesRepository;
exports.DeparturesRepository = DeparturesRepository = __decorate([
    (0, tsyringe_1.injectable)(),
    __param(0, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.PostgresConnector)),
    __param(1, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.SimpleConfig)),
    __metadata("design:paramtypes", [Object, Object])
], DeparturesRepository);
//# sourceMappingURL=DeparturesRepository.js.map