# frozen_string_literal: true

require 'litany/mixins/stack'
require 'litany/meta_resources/environment'

module Litany

  # A meta resource stack that provides the boilerplate building blocks for Arcana integration
  #   Is somewhat unique in that this is expected to be a singleton and live in every region.
  class ArcanaSupport < MetaResource
    include Stack

    flag :automatic, false

    property :admin_role, nil, [String, Symbol]

    resource_collection KMSKey, :key
    resource_collection S3Bucket, :s3bucket

    resource_references Environment, :environment

    validator(:broken_singleton) do
      count = ArcanaSupport.instances.count
      raise "Some how there are #{count} instances of ArcanaClient.  There should never be more than one." if count > 1
    end

    # Returns the arcana bucket
    # @return [S3Bucket]
    def bucket
      s3bucket(:arcana)
    end

    # Enforces a few standards
    # @return [void]
    def finalize_resource
      bucket.futures_unique_naming
      kms_key.allow(:full, role: admin_role)
    end

    # Hooks to ensure ArcanaSupport is in every region
    # @return [void]
    def finalize_stack
      # Make sure we're in all environments
      Environment.instances.each_value do |env|
        environment(env) unless environments.include?(env)
        bucket.environment(env) unless bucket.environments.include?(env)
      end

      super
    end

    # Returns the kms key for project level secrets
    # @return [KMSKey]
    def kms_key
      key(project.service_id)
    end

    class << self
      # Tests if ArcanaSupport should be automatically enabled for services and instances.
      # @return [Boolean]
      def automatic?
        enabled? && instance.automatic?
      end

      # Tests if ArcanaSupport is enabled at the project level
      # @return [Boolean]
      def enabled?
        instances.count == 1
      end

      # Returns the singleton instance if it exists
      # @return [ArcanaSupport]
      def instance
        instances.values.first
      end
    end
  end
end

