# frozen_string_literal: true

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

module Litany
  class ApplicationLoadBalancerListener < Resource
    cfn_type 'AWS::ElasticLoadBalancingV2::Listener'
    parent_resource :load_balancer

    child_resource ApplicationLoadBalancerFixedResponse, :fixed_response, automatic: :on_access

    flag :support_xp, false

    property :port, nil, 1..65_535
    property :protocol, :https, [:http, :https]

    resource_collection ApplicationLoadBalancerListenerRule, :rule, required: false

    resource_reference ApplicationLoadBalancerTargetGroup, :target_group, required: false
    resource_reference Certificate, :certificate, required: false

    validator :default_action_jeopardy do
      raise 'You must specify either a fixed_response or a target_group but not both.' unless set_fixed_response? ^ set_target_group?
    end

    validator :ssl_configuration do
      protocol :https unless certificate.nil?
      raise 'Certificates must be set if protocol is set to https.' unless http? || set_certificate?
    end

    def finalize_resource
      port(https? ? 443 : 80) unless set_port?
    end

    def http?
      protocol == :http
    end

    def https?
      protocol == :https
    end

    def properties
      props = {
        DefaultActions: [],
        LoadBalancerArn: ref(load_balancer),
        Port: (port || (https? ? 443 : 80)),
        Protocol: protocol.upcase
      }

      props[:Certificates] = [{CertificateArn: ref(certificate)}] if https?
      props[:SslPolicy] = 'ELBSecurityPolicy-TLS-1-0-2015-04' if support_xp?

      props[:DefaultActions] << { FixedResponseConfig: fixed_response, Type: 'fixed-response' } if set_fixed_response?
      props[:DefaultActions] << { TargetGroupArn: ref(target_group), Type: :forward } if set_target_group?

      props
    end
  end
end
