# frozen_string_literal: true

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

module Litany
  class AutoScalingGroup < Resource
    include Taggable

    cfn_type 'AWS::AutoScaling::AutoScalingGroup'

    property :cooldown, 300, [nil, 30..3600]
    property :desired_size, nil, [nil, Integer]
    property :max_size, 1, Integer
    property :min_size, 1, Integer

    resource_reference AutoScalingLaunchConfiguration, :launch_configuration, inherited: true
    resource_reference VPC, :vpc, inherited: true

    resource_references ApplicationLoadBalancerTargetGroup, :target_group, inherited: true, required: false
    resource_references ElasticLoadBalancer, :load_balancer, inherited: true, required: false

    validator(:size) do
      raise 'You may not have a `max_size` smaller than the `min_size`.' if max_size < min_size
      raise 'You may not set `desired_size` less than the `max_size`.' if set_desired_size? && max_size < desired_size
      raise 'You may not have a negative `max_size` or `min_size`.' if max_size.negative? || min_size.negative?
    end

    def compiled_tags
      # These tags are S P E C I A L
      tags = super.collect(&:clone)
      tags.each { |tag| tag[:PropagateAtLaunch] = true }
      tags
    end

    def properties
      # TODO: HealthCheckGracePeriod, HealthCheckType, NotificationConfigurations, TerminationPolicies
      # Not implementing: AvailabilityZones, InstanceId, PlacementGroup

      props = {
        LaunchConfigurationName: ref(launch_configuration),
        MaxSize: max_size,
        MetricsCollection: [{Granularity: '1Minute'}],
        MinSize: min_size,
        VPCZoneIdentifier: ref(vpc.subnets)
      }

      props[:Cooldown] = cooldown.to_s if set_cooldown?
      props[:DesiredCapacity] = desired_size if set_desired_size?
      props[:TargetGroupARNs] = ref(target_groups)  if set_target_groups?
      props[:LoadBalancerNames] = ref(load_balancers) if set_load_balancers?

      props
    end

    def default_tags
      {
          LitanyAutoScalingGroupName: self.name,
      }
    end
  end
end
