# frozen_string_literal: true

require 'litany/mixins'
require 'litany/resource'

module Litany
  class EventsRule < Resource
    cfn_type 'AWS::Events::Rule'

    property :description, nil, [nil, String]

    # See http://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html for syntax
    property :schedule, nil, [nil, String]

    # See https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEventsandEventPatterns.html for syntax
    property :pattern, nil, [nil, Hash]

    property :enabled, true, [true, false]

    resource_reference LambdaFunction, :target_lambda, required: false
    resource_reference SNSTopic, :target_topic, required: false
    resource_reference SQSQueue, :target_queue, required: false
    resource_reference KinesisStream, :target_stream, required: false

    validator(:target_jeopardy) do
      raise "Can't specify both Schedule and Pattern for event" if (set_pattern? && set_schedule?)
      raise 'Must specify one of Schedule and Pattern for event' unless (set_pattern? || set_schedule?)

      raise "You must provide exactly one of 'target_lambda', 'target_topic', 'target_queue', or 'target_stream'" unless set_target_lambda? ^ set_target_topic? ^ set_target_queue? ^ set_target_stream?
    end

    def properties
      props = {
        State: enabled ? 'ENABLED' : 'DISABLED',
        Targets: [
          {
            Id: "#{target.name}_scheduler",
            Arn: target.is_a?(SNSTopic) ? ref(target) : ref(target, :Arn)
          }
        ]
      }

      props[:EventPattern] = pattern if set_pattern?
      props[:ScheduleExpression] = schedule if set_schedule?
      props[:Description] = description if set_description?

      props[:Targets][0][:SqsParameters] = { MessageGroupId: 'scheduler' } if target.is_a?(SQSQueue) && target.fifo?

      props
    end

    def target
      target_lambda || target_topic || target_queue || target_stream
    end
  end
end
