"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const cdk_1 = require("@aws-cdk/cdk");
const events_generated_1 = require("./events.generated");
const rule_ref_1 = require("./rule-ref");
const util_1 = require("./util");
/**
 * Defines a CloudWatch Event Rule in this stack.
 */
class EventRule extends rule_ref_1.EventRuleRef {
    constructor(parent, name, props = {}) {
        super(parent, name);
        this.targets = new Array();
        this.eventPattern = {};
        const resource = new events_generated_1.cloudformation.RuleResource(this, 'Resource', {
            description: props.description,
            state: props.enabled == null ? 'ENABLED' : (props.enabled ? 'ENABLED' : 'DISABLED'),
            scheduleExpression: new cdk_1.Token(() => this.scheduleExpression),
            eventPattern: new cdk_1.Token(() => this.renderEventPattern()),
            targets: new cdk_1.Token(() => this.renderTargets())
        });
        this.ruleArn = resource.ruleArn;
        this.addEventPattern(props.eventPattern);
        this.scheduleExpression = props.scheduleExpression;
        for (const target of props.targets || []) {
            this.addTarget(target);
        }
    }
    /**
     * Adds a target to the rule. The abstract class RuleTarget can be extended to define new
     * targets.
     *
     * No-op if target is undefined.
     */
    addTarget(target, inputOptions) {
        if (!target) {
            return;
        }
        const targetProps = target.asEventRuleTarget(this.ruleArn, this.uniqueId);
        // check if a target with this ID already exists
        if (this.targets.find(t => t.id === targetProps.id)) {
            throw new Error('Duplicate event rule target with ID: ' + targetProps.id);
        }
        this.targets.push(Object.assign({}, targetProps, { inputTransformer: renderTransformer() }));
        function renderTransformer() {
            if (!inputOptions) {
                return undefined;
            }
            if (inputOptions.jsonTemplate && inputOptions.textTemplate) {
                throw new Error('"jsonTemplate" and "textTemplate" are mutually exclusive');
            }
            if (!inputOptions.jsonTemplate && !inputOptions.textTemplate) {
                throw new Error('One of "jsonTemplate" or "textTemplate" are required');
            }
            let inputTemplate;
            if (inputOptions.jsonTemplate) {
                inputTemplate = inputOptions.jsonTemplate;
            }
            else if (typeof (inputOptions.textTemplate) === 'string') {
                inputTemplate = JSON.stringify(inputOptions.textTemplate);
            }
            else {
                inputTemplate = new cdk_1.FnConcat('"', inputOptions.textTemplate, '"');
            }
            return {
                inputPathsMap: inputOptions.pathsMap,
                inputTemplate
            };
        }
    }
    /**
     * Adds an event pattern filter to this rule. If a pattern was already specified,
     * these values are merged into the existing pattern.
     *
     * For example, if the rule already contains the pattern:
     *
     *      {
     *          "resources": [ "r1" ],
     *          "detail": {
     *              "hello": [ 1 ]
     *          }
     *      }
     *
     * And `addEventPattern` is called with the pattern:
     *
     *      {
     *          "resources": [ "r2" ],
     *          "detail": {
     *              "foo": [ "bar" ]
     *          }
     *      }
     *
     * The resulting event pattern will be:
     *
     *      {
     *          "resources": [ "r1", "r2" ],
     *          "detail": {
     *              "hello": [ 1 ],
     *              "foo": [ "bar" ]
     *          }
     *      }
     *
     */
    addEventPattern(eventPattern) {
        if (!eventPattern) {
            return;
        }
        util_1.mergeEventPattern(this.eventPattern, eventPattern);
    }
    validate() {
        if (Object.keys(this.eventPattern).length === 0 && !this.scheduleExpression) {
            return [`Either 'eventPattern' or 'scheduleExpression' must be defined`];
        }
        return [];
    }
    renderTargets() {
        if (this.targets.length === 0) {
            return undefined;
        }
        return this.targets;
    }
    renderEventPattern() {
        const eventPattern = this.eventPattern;
        if (Object.keys(eventPattern).length === 0) {
            return undefined;
        }
        // rename 'detailType' to 'detail-type'
        const out = {};
        for (let key of Object.keys(eventPattern)) {
            const value = eventPattern[key];
            if (key === 'detailType') {
                key = 'detail-type';
            }
            out[key] = value;
        }
        return out;
    }
}
exports.EventRule = EventRule;
//# sourceMappingURL=data:application/json;base64, 