# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
# frozen_string_literal: true

require 'contrast/components/base'
require 'contrast/config/base_configuration'

module Contrast
  module Components
    module HeapDump
      # Interface used to build the HeapDump settings and component.
      class Interface
        include Contrast::Config::BaseConfiguration
        include Contrast::Components::ComponentBase

        # @return [String]
        attr_reader :canon_name
        # @return [Array]
        attr_reader :config_values

        DEFAULT_PATH = 'contrast_heap_dumps' # saved
        DEFAULT_MS = 10_000
        DEFAULT_COUNT = 5
        CANON_NAME = 'agent.heap_dump'
        CONFIG_VALUES = %w[enable path delay_ms window_ms count clean].cs__freeze

        def initialize hsh = {}
          @config_values = CONFIG_VALUES
          @canon_name = CANON_NAME
          return unless hsh

          @_enable = hsh[:enable]
          @_path = hsh[:path]
          @_delay_ms = hsh[:delay_ms]
          @_window_ms = hsh[:window_ms]
          @_count = hsh[:count]
          @_clean = hsh[:clean]
        end

        # @return [Boolean, String] should dumps be taken
        def enable
          @_enable.nil? ? Contrast::Utils::ObjectShare::FALSE : @_enable
        end

        # @return [String, DEFAULT_PATH] dir to which dumps should be
        def path
          @_path ||= DEFAULT_PATH
        end

        # @return [Integer, DEFAULT_MS] time, in ms, after initialization
        def delay_ms
          @_delay_ms ||= DEFAULT_MS
        end

        # @return [Integer, DEFAULT_MS] ms between each dump
        def window_ms
          @_window_ms ||= DEFAULT_MS
        end

        # @return [Integer, DEFAULT_COUNT] number of dumps to take
        def count
          @_count ||= DEFAULT_COUNT
        end

        # @return [Boolean, String] remove temporary objects or not
        def clean
          @_clean.nil? ? Contrast::Utils::ObjectShare::FALSE : @_clean
        end
      end

      # A wrapper build around the Common Agent Configuration project to allow
      # for access of the values contained in its
      # parent_configuration_spec.yaml.
      # Specifically, this allows for querying the state of the Heap Dump
      # utility.
      module ClassMethods
        include Contrast::Components::ComponentBase

        def heap_dump_enabled?
          heap_dump_control[:enabled]
        end

        def heap_dump_control
          @_heap_dump_control ||= begin
            config = ::Contrast::CONFIG&.agent&.heap_dump
            {
                enabled: true?(config&.enable),
                path: File.absolute_path(config&.path),
                count: config&.count.to_i || 0,
                window: (config&.window_ms.to_f || 0) / 1000,
                delay: (config&.delay_ms.to_f || 0) / 1000,
                clean: true?(config&.clean)
            }
          end
        end
      end
      InstanceMethods = ClassMethods
    end
  end
end