# frozen_string_literal: true

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

module Litany
  class KinesisStream < Resource
    include Taggable

    output
    output :Arn

    cfn_type 'AWS::Kinesis::Stream'

    property :over_utilization_threshold, 85, 1..100
    property :retention, 24, 1..100_000
    property :shards, 1, 1..100_000
    property :stream_name, nil, [nil, String]
    property :under_utilization_threshold, 1, 1..100

    resource_collection CloudWatchAlarm, :alarm

    def default_stream_name
      seed = "#{name}-#{project.stage}-#{active_environment_name}"
      "#{seed}-#{Digest::SHA256.hexdigest(seed)}".tr('_', '-')[0..126].downcase
    end

    def finalize_resource
      max_bytes = shards * 1_000_000 * 60
      name = stream_name || default_stream_name
      over = over_utilization_threshold
      under = under_utilization_threshold

      alarm(:"#{name}_stream_over_utilized") do
        description "More than #{over}% of max bytes sent."
        dimension
        metric 'IncomingBytes'
        missing_data :not_breaching
        operator :greater_than
        occurrences 2
        statistic :sum
        threshold max_bytes * over / 100
        unit :bytes
      end

      alarm(:"#{name}_stream_under_utilized") do
        description "Fewer than #{under}% of max bytes sent."
        metric 'IncomingBytes'
        occurrences 2
        statistic :sum
        threshold max_bytes * under / 100
        unit :bytes
      end
    end

    def properties
      {
        Name: stream_name || default_stream_name,
        RetentionPeriodHours: retention,
        ShardCount: shards,
      }
    end
  end
end