"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.JISInfotextRepository = void 0;
const GTFSStopModel_1 = require("../../ropid-gtfs/models/GTFSStopModel");
const const_1 = require("../../../schema-definitions/const");
const JISInfotextsModel_1 = require("../../../schema-definitions/jis/models/JISInfotextsModel");
const AbstractBasicRepository_1 = require("@golemio/core/dist/helpers/data-access/postgres/repositories/AbstractBasicRepository");
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 OgPidToken_1 = require("../ioc/OgPidToken");
const JISInfotextRopidGTFSStopsRepository_1 = require("./JISInfotextRopidGTFSStopsRepository");
let JISInfotextRepository = class JISInfotextRepository extends AbstractBasicRepository_1.AbstractBasicRepository {
    constructor(infotextStopRepository, connector, logger) {
        super(connector, logger);
        this.schema = const_1.PG_SCHEMA;
        this.tableName = JISInfotextsModel_1.JISInfotextsModel.tableName;
        this.sequelizeModel = connector
            .getConnection()
            .define(this.tableName, JISInfotextsModel_1.JISInfotextsModel.attributeModel, { schema: this.schema, timestamps: false });
        this.gtfsStopRepository = new GTFSStopModel_1.GTFSStopModel();
        // associations
        this.sequelizeModel.belongsToMany(this.gtfsStopRepository.sequelizeModel, {
            through: infotextStopRepository.sequelizeModel,
            foreignKey: "infotext_id",
            otherKey: "stop_id",
            as: "stops",
        });
        this.gtfsStopRepository.sequelizeModel.belongsToMany(this.sequelizeModel, {
            through: infotextStopRepository.sequelizeModel,
            foreignKey: "stop_id",
            otherKey: "infotext_id",
        });
        infotextStopRepository.sequelizeModel.belongsTo(this.sequelizeModel, {
            targetKey: "id",
            foreignKey: "infotext_id",
        });
        infotextStopRepository.sequelizeModel.belongsTo(this.gtfsStopRepository.sequelizeModel, {
            targetKey: "stop_id",
            foreignKey: "stop_id",
        });
        this.sequelizeModel.hasMany(infotextStopRepository.sequelizeModel, {
            sourceKey: "id",
            foreignKey: "infotext_id",
        });
        this.gtfsStopRepository.sequelizeModel.hasMany(infotextStopRepository.sequelizeModel, {
            sourceKey: "stop_id",
            foreignKey: "stop_id",
        });
    }
    /**
     * Find all active infotexts for given stops and time for PID departure boards API
     *
     * @param stopsIds GTFS stop IDs for which the infotexts should be fetched
     * @param timeFrom Time from which the infotexts should be valid (default is current time)
     * @returns Active infotexts
     */
    async findAllForDepartureBoard(stopsIds, timeFrom = new Date()) {
        try {
            return await this.sequelizeModel.findAll({
                attributes: ["display_type", "active_period_start", "active_period_end", "description_text", "severity_level"],
                where: {
                    active_period_start: { [sequelize_1.Op.lte]: timeFrom },
                    active_period_end: { [sequelize_1.Op.or]: [{ [sequelize_1.Op.gte]: timeFrom }, { [sequelize_1.Op.is]: null }] },
                },
                include: [
                    {
                        model: this.gtfsStopRepository.sequelizeModel,
                        as: "stops",
                        attributes: ["stop_id"],
                        where: {
                            stop_id: { [sequelize_1.Op.in]: stopsIds },
                        },
                        through: { attributes: [] },
                        required: true,
                    },
                ],
                order: [
                    // severity_level is an enum, see type jis_infotext_severity_level
                    ["severity_level", "DESC"],
                    ["created_timestamp", "DESC"],
                ],
            });
        }
        catch (err) {
            throw new golemio_errors_1.GeneralError("Error while getting infotexts for departure board", this.constructor.name, err);
        }
    }
    /**
     * Find all infotexts for given time for PID infotexts API
     *
     * @param includeFuture if false return just active infotexts
     * @returns infotexts
     */
    async findAllForOverview(includeFuture) {
        try {
            const now = new Date();
            const where = {
                active_period_end: { [sequelize_1.Op.or]: [{ [sequelize_1.Op.gte]: now }, { [sequelize_1.Op.is]: null }] },
            };
            if (!includeFuture) {
                where.active_period_start = { [sequelize_1.Op.lte]: now };
            }
            return await this.sequelizeModel.findAll({
                attributes: [
                    "id",
                    "display_type",
                    "active_period_start",
                    "active_period_end",
                    "description_text",
                    "severity_level",
                ],
                where,
                include: [
                    {
                        model: this.gtfsStopRepository.sequelizeModel,
                        as: "stops",
                        attributes: ["stop_id", "stop_name", "platform_code"],
                        through: { attributes: [] },
                        required: true,
                    },
                ],
                order: [
                    // severity_level is an enum, see type jis_infotext_severity_level
                    ["severity_level", "DESC"],
                    ["created_timestamp", "DESC"],
                ],
            });
        }
        catch (err) {
            throw new golemio_errors_1.GeneralError("Error while getting infotexts for overview", this.constructor.name, err);
        }
    }
};
exports.JISInfotextRepository = JISInfotextRepository;
exports.JISInfotextRepository = JISInfotextRepository = __decorate([
    (0, tsyringe_1.injectable)(),
    __param(0, (0, tsyringe_1.inject)(OgPidToken_1.OgPidToken.JISInfotextRopidGTFSStopsRepository)),
    __param(1, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.PostgresConnector)),
    __param(2, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.Logger)),
    __metadata("design:paramtypes", [JISInfotextRopidGTFSStopsRepository_1.JISInfotextRopidGTFSStopsRepository, Object, Object])
], JISInfotextRepository);
//# sourceMappingURL=JISInfotextRepository.js.map