# frozen_string_literal: true

require 'litany/resource'

module Litany
  class InstanceProfileRole < Resource
    cfn_type 'AWS::IAM::Role'
    parent_resource :instance_profile

    child_resource IAMPolicyDocument, :sts_policy

    output 'Arn'

    property :path, '/', [String]
    property :trusted_services, ['ec2.amazonaws.com'], Array, inherited: true

    property_collection :managed_policy, [], String, required: false

    resource_collection IAMPolicyDocument, :policy, required: false

    def allow(actions:, resource:)
      allowed_actions = (actions.is_a?(String) ? [actions] : actions)
      next_policy do
        next_statement do
          actions allowed_actions
          on_resource resource
        end
      end
    end

    def finalize_resource
      services = self.trusted_services # Scoping gotcha
      sts_policy.next_statement do
        actions 'sts:AssumeRole'
        services.each { |svc| allow_principal service: svc }
      end
    end

    def next_policy(&block)
      @next_policy_id ||= 0
      policy format("#{name}_Policy%03d", @next_policy_id += 1).to_sym, &block
    end

    def properties
      props = {
        AssumeRolePolicyDocument: sts_policy,
        Path: path,
        RoleName: role_name
      }

      props[:ManagedPolicyArns] = managed_policies if set_managed_policies?
      props[:Policies] = policies.map { |p| {PolicyName: p.name.pascal_case, PolicyDocument: p} } unless policies.empty?

      props
    end

    def role_name
      "#{resource_name}-#{active_environment.pretty_region}-#{Digest::SHA256.hexdigest(output_name)}".tr('_', '-')[0..62]
    end
  end
end
