class Inspec::ControlEvalContext


etc).
as the basic DSL of the control files (describe, control, title,
The anonymous class includes the given passed resource_dsl as well
files will be instance_exec’d against.
ControlEvalContext constructs an anonymous class that control

def add_resource(name, new_res)

def add_resource(name, new_res)
  resources_dsl.module_exec do
    define_method name.to_sym do |*args|
      new_res.new(@backend, name.to_s, *args)
    end
  end
end

def add_resources(context)

def add_resources(context)
  # # TODO: write real unit tests for this and then make this change:
  # dsl = context.to_resources_dsl
  # self.class.include dsl
  # Inspec::Rule.include dsl
  self.class.class_eval do
    include context.to_resources_dsl
  end
  # TODO: seriously consider getting rid of the NPM model
  extend context.to_resources_dsl
end

def add_subcontext(context)

def add_subcontext(context)
  profile_context_owner.add_subcontext(context)
end

def attribute(name, options = {})

def attribute(name, options = {})
  Inspec.deprecate(:attrs_dsl, "Input name: #{name}, Profile: #{profile_id}")
  input(name, options)
end

def block_location(block, alternate_caller)

def block_location(block, alternate_caller)
  if block.nil?
    alternate_caller[/^(.+:\d+):in .+$/, 1] || "unknown"
  else
    path, line = block.source_location
    "#{File.basename(path)}:#{line}"
  end
end

def control(id, opts = {}, &block)

def control(id, opts = {}, &block)
  opts[:skip_only_if_eval] = @skip_only_if_eval
  if (controls_list_empty? && tags_list_empty?) || control_exist_in_controls_list?(id)
    register_control(Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block))
  elsif !tags_list_empty?
    # Inside elsif rule is initialised before registering it because it enables fetching of control tags
    # This condition is only true when --tags option is used
    inspec_rule = Inspec::Rule.new(id, profile_id, resources_dsl, opts, &block)
    tag_ids = control_tags(inspec_rule)
    register_control(inspec_rule) if tag_exist_in_control_tags?(tag_ids)
  end
end

def control_exist_in_controls_list?(id)

Check if the given control exist in the --controls option
def control_exist_in_controls_list?(id)
  id_exist_in_list = false
  if profile_config_exist?
    id_exist_in_list = @conf["profile"].include_controls_list.any? do |inclusion|
      # Try to see if the inclusion is a regex, and if it matches
      inclusion == id || (inclusion.is_a?(Regexp) && inclusion =~ id)
    end
  end
  id_exist_in_list
end

def control_tags(inspec_rule)

def control_tags(inspec_rule)
  all_tags = []
  inspec_rule.tag.each do |key, value|
    all_tags.push(key)
    all_tags.push(value) unless value.nil?
  end
  all_tags.flatten.compact.uniq.map(&:to_s)
rescue
  []
end

def controls_list_empty?

Returns true if configuration hash is empty or configuration hash does not have the list of controls that needs to be included
def controls_list_empty?
  !@conf.empty? && @conf.key?("profile") && @conf["profile"].include_controls_list.empty? || @conf.empty?
end

def describe(*args, &block)


the describe block in the context of that control.
generate a control for them automatically and then execute
blocks without declaring an inclosing control. Here, we
Describe allows users to write rspec-like bare describe
def describe(*args, &block)
  loc = block_location(block, caller(1..1).first)
  id = "(generated from #{loc} #{SecureRandom.hex})"
  res = nil
  rule = Inspec::Rule.new(id, profile_id, resources_dsl, {}) do
    res = describe(*args, &block)
  end
  if controls_list_empty? || control_exist_in_controls_list?(id)
    register_control(rule, &block)
  end
  res
end

def initialize(profile_context, resources_dsl, backend, conf, dependencies, require_loader, skip_only_if_eval)

def initialize(profile_context, resources_dsl, backend, conf, dependencies, require_loader, skip_only_if_eval)
  @profile_context = profile_context
  @resources_dsl = resources_dsl
  @backend = backend
  @conf = conf
  @dependencies = dependencies
  @require_loader = require_loader
  @skip_file_message = nil
  @skip_file = false
  @skip_only_if_eval = skip_only_if_eval
  extend resources_dsl # TODO: remove? push to method_missing?
end

def input(input_name, options = {})

def input(input_name, options = {})
  if options.empty?
    # Simply an access, no event here
    Inspec::InputRegistry.find_or_register_input(input_name, profile_id).value
  else
    options[:priority] ||= 20
    options[:provider] = :inline_control_code
    evt = Inspec::Input.infer_event(options)
    Inspec::InputRegistry.find_or_register_input(input_name, profile_id, event: evt).value
  end
end

def input_object(input_name)

Will return nil on a miss.
Find the Input object, but don't collapse to a value.
def input_object(input_name)
  Inspec::InputRegistry.find_or_register_input(input_name, profile_id)
end

def only_if(message = nil, &block)

def only_if(message = nil, &block)
  return unless block
  return if @skip_file == true
  return if @skip_only_if_eval == true
  return if block.yield == true
  # Apply `set_skip_rule` for other rules in the same file
  profile_context_owner.rules.values.each do |r|
    sources_match = r.source_file == block.source_location[0]
    Inspec::Rule.set_skip_rule(r, true, message) if sources_match
  end
  @skip_file_message = message
  @skip_file = true
end

def profile_config_exist?

Returns true if configuration hash is not empty and it contains the list of controls is not empty
def profile_config_exist?
  !@conf.empty? && @conf.key?("profile") && !@conf["profile"].include_controls_list.empty?
end

def profile_id

def profile_id
  profile_context.profile_id
end

def profile_name

def profile_name
  profile_id
end

def profile_tag_config_exist?

def profile_tag_config_exist?
  !@conf.empty? && @conf.key?("profile") && !@conf["profile"].include_tags_list.empty?
end

def register_control(control, &block)

def register_control(control, &block)
  if @skip_file
    ::Inspec::Rule.set_skip_rule(control, true, @skip_file_message)
  end
  unless profile_context_owner.profile_supports_platform?
    platform = inspec.platform
    msg = "Profile `#{profile_id}` is not supported on platform #{platform.name}/#{platform.release}."
    ::Inspec::Rule.set_skip_rule(control, true, msg)
  end
  unless profile_context_owner.profile_supports_inspec_version?
    msg = "Profile `#{profile_id}` is not supported on InSpec version (#{Inspec::VERSION})."
    ::Inspec::Rule.set_skip_rule(control, true, msg)
  end
  profile_context_owner.register_rule(control, &block) unless control.nil?
end

def skip_control(id)

def skip_control(id)
  profile_context_owner.unregister_rule(id)
end

def tag_exist_in_control_tags?(tag_ids)

Check if the given control exist in the --tags option
def tag_exist_in_control_tags?(tag_ids)
  tag_option_matches_with_list = false
  if !tag_ids.empty? && !tag_ids.nil? && profile_tag_config_exist?
    tag_option_matches_with_list = !(tag_ids & @conf["profile"].include_tags_list).empty?
    unless tag_option_matches_with_list
      @conf["profile"].include_tags_list.any? do |inclusion|
        # Try to see if the inclusion is a regex, and if it matches
        if inclusion.is_a?(Regexp)
          tag_ids.each do |id|
            tag_option_matches_with_list = (inclusion =~ id)
            break if tag_option_matches_with_list
          end
        end
      end
    end
  end
  tag_option_matches_with_list
end

def tags_list_empty?

def tags_list_empty?
  !@conf.empty? && @conf.key?("profile") && @conf["profile"].include_tags_list.empty? || @conf.empty?
end

def title(arg)

def title(arg)
  profile_context_owner.set_header(:title, arg)
end

def to_s

def to_s
  "Control Evaluation Context (#{profile_name})"
end