"use strict";
/*
 * server component for the TimeLimit App
 * Copyright (C) 2019 - 2020 Jonas Lochmann
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.AddUsedTimeActionVersion2 = void 0;
const minuteofday_1 = require("../util/minuteofday");
const basetypes_1 = require("./basetypes");
const exception_1 = require("./meta/exception");
const util_1 = require("./meta/util");
const actionType = 'AddUsedTimeActionVersion2';
class AddUsedTimeActionVersion2 extends basetypes_1.AppLogicAction {
    constructor({ dayOfEpoch, items, trustedTimestamp }) {
        super();
        (0, util_1.assertSafeInteger)({ actionType, field: 'dayOfEpoch', value: dayOfEpoch });
        if (dayOfEpoch < 0) {
            (0, util_1.throwOutOfRange)({ actionType, field: 'dayOfEpoch', value: dayOfEpoch });
        }
        (0, util_1.assertSafeInteger)({ actionType, field: 'trustedTimestamp', value: trustedTimestamp });
        if (trustedTimestamp < 0) {
            (0, util_1.throwOutOfRange)({ actionType, field: 'trustedTimestamp', value: trustedTimestamp });
        }
        if (items.length === 0) {
            throw new exception_1.InvalidActionParameterException({ actionType, staticMessage: 'no items' });
        }
        (0, util_1.assertListWithoutDuplicates)({
            actionType,
            field: 'categoryIds',
            list: items.map((item) => item.categoryId)
        });
        items.forEach((item) => {
            (0, util_1.assertIdWithinFamily)({ actionType, field: 'categoryId', value: item.categoryId });
            (0, util_1.assertSafeInteger)({ actionType, field: 'timeToAdd', value: item.timeToAdd });
            if (item.timeToAdd < 0) {
                (0, util_1.throwOutOfRange)({ actionType, field: 'timeToAdd', value: item.timeToAdd });
            }
            (0, util_1.assertSafeInteger)({ actionType, field: 'extraTimeToSubtract', value: item.extraTimeToSubtract });
            if (item.extraTimeToSubtract < 0) {
                (0, util_1.throwOutOfRange)({ actionType, field: 'extraTimeToSubtract', value: item.extraTimeToSubtract });
            }
            (0, util_1.assertListWithoutDuplicates)({
                actionType,
                field: 'additionalCountingSlots',
                list: item.additionalCountingSlots.map((item) => JSON.stringify(item.serialize()))
            });
            (0, util_1.assertListWithoutDuplicates)({
                actionType,
                field: 'sessionDurationLimits',
                list: item.sessionDurationLimits.map((item) => JSON.stringify(item.serialize()))
            });
        });
        this.dayOfEpoch = dayOfEpoch;
        this.items = items;
        this.trustedTimestamp = trustedTimestamp;
    }
}
exports.AddUsedTimeActionVersion2 = AddUsedTimeActionVersion2;
AddUsedTimeActionVersion2.parse = ({ d, i, t }) => (new AddUsedTimeActionVersion2({
    dayOfEpoch: d,
    items: i.map((item) => {
        var _a, _b;
        return ({
            categoryId: item.categoryId,
            timeToAdd: item.tta,
            extraTimeToSubtract: item.etts,
            sessionDurationLimits: ((_a = item.sdl) !== null && _a !== void 0 ? _a : []).map((item) => AddUsedTimeActionItemSessionDurationLimitSlot.parse(item)),
            additionalCountingSlots: ((_b = item.as) !== null && _b !== void 0 ? _b : []).map((item) => AddUsedTimeActionItemAdditionalCountingSlot.parse(item))
        });
    }),
    trustedTimestamp: t !== null && t !== void 0 ? t : 0
}));
class AddUsedTimeActionItemAdditionalCountingSlot {
    constructor({ start, end }) {
        this.serialize = () => [this.start, this.end];
        (0, util_1.assertSafeInteger)({ actionType, field: 'start', value: start });
        (0, util_1.assertSafeInteger)({ actionType, field: 'end', value: end });
        if (start < minuteofday_1.MinuteOfDay.MIN || end > minuteofday_1.MinuteOfDay.MAX || start > end) {
            throw new exception_1.InvalidActionParameterException({ actionType, staticMessage: 'start or end out of range' });
        }
        if (start === minuteofday_1.MinuteOfDay.MIN && end === minuteofday_1.MinuteOfDay.MAX) {
            throw new exception_1.InvalidActionParameterException({ actionType, staticMessage: 'couting slot can not fill the whole day' });
        }
        this.start = start;
        this.end = end;
    }
}
AddUsedTimeActionItemAdditionalCountingSlot.parse = ([start, end]) => new AddUsedTimeActionItemAdditionalCountingSlot({ start, end });
class AddUsedTimeActionItemSessionDurationLimitSlot {
    constructor({ start, end, duration, pause }) {
        this.serialize = () => [this.start, this.end, this.duration, this.pause];
        (0, util_1.assertSafeInteger)({ actionType, field: 'start', value: start });
        (0, util_1.assertSafeInteger)({ actionType, field: 'end', value: end });
        (0, util_1.assertSafeInteger)({ actionType, field: 'duration', value: duration });
        (0, util_1.assertSafeInteger)({ actionType, field: 'pause', value: pause });
        if (start < minuteofday_1.MinuteOfDay.MIN || end > minuteofday_1.MinuteOfDay.MAX || start > end) {
            throw new exception_1.InvalidActionParameterException({ actionType, staticMessage: 'start or end out of range' });
        }
        if (duration <= 0 || pause <= 0) {
            throw new exception_1.InvalidActionParameterException({ actionType, staticMessage: 'duration and pause must not be zero or smaller' });
        }
        this.start = start;
        this.end = end;
        this.duration = duration;
        this.pause = pause;
    }
}
AddUsedTimeActionItemSessionDurationLimitSlot.parse = ([start, end, duration, pause]) => new AddUsedTimeActionItemSessionDurationLimitSlot({ start, end, duration, pause });
//# sourceMappingURL=addusedtime2.js.map