module Ariadne::FetchOrFallbackHelper

def check_incoming_attribute(preferred_attribute, given_attribute)

TODO: test this
def check_incoming_attribute(preferred_attribute, given_attribute)
  return preferred_attribute if given_attribute.blank? || preferred_attribute != given_attribute
  unless silence_warnings?
    message = <<~MSG
      Ariadne: note that `#{preferred_attribute}` is the preferred attribute for `#{self.class.name}`;
      you passed `#{given_attribute}` (which will still be used)
    MSG
    logger.warn(message)
  end
  given_attribute
end

def check_incoming_tag(preferred_tag, given_tag)

TODO: test this
def check_incoming_tag(preferred_tag, given_tag)
  return preferred_tag if given_tag.blank? || preferred_tag == given_tag
  unless silence_warnings?
    message = <<~MSG
      Ariadne: note that `#{preferred_tag}` is the preferred tag for `#{self.class.name}`;
      you passed `#{given_tag}` (which will still be used)
    MSG
    logger.warn(message)
  end
  given_tag
end

def check_incoming_value(preferred_value, given_pair)

TODO: test this
def check_incoming_value(preferred_value, given_pair)
  return preferred_value if given_pair.blank? || !given_pair.is_a?(Hash)
  given_key = given_pair.keys.first
  given_value = given_pair.values.first
  return preferred_value if given_value.blank?
  unless silence_warnings?
    message = <<~MSG
      Ariadne: note that `#{preferred_value}` is the preferred value for `#{given_key}` here;
      you passed `#{given_value}` (which will still be used)
    MSG
    logger.warn(message)
  end
  given_value
end

def fetch_or_fallback(allowed_values, given_value, fallback = nil, deprecated_values: nil)

def fetch_or_fallback(allowed_values, given_value, fallback = nil, deprecated_values: nil)
  if allowed_values.include?(given_value)
    given_value
  elsif deprecated_values&.include?(given_value)
    ::Ariadne::ViewComponents.deprecation.warn("#{given_value} is deprecated and will be removed in a future version.") unless Rails.env.production? || silence_deprecations?
    given_value
  else
    if fallback_raises && ENV["RAILS_ENV"] != "production"
      raise InvalidValueError, <<~MSG
        fetch_or_fallback was called with an invalid value.
        Expected one of: #{allowed_values.inspect}
        Got: #{given_value.inspect}
        This will not raise in production, but will instead fallback to: #{fallback.inspect}
      MSG
    end
    fallback
  end
end

def fetch_or_raise(allowed_values, given_value, against: nil)

def fetch_or_raise(allowed_values, given_value, against: nil)
  if !allowed_values.is_a?(Array) && !allowed_values.is_a?(Set)
    raise ArgumentError, "allowed_values must be an array or a set; it was #{allowed_values.class}"
  end
  check_against_given_value = against || given_value
  if allowed_values.include?(check_against_given_value)
    given_value
  elsif fallback_raises
    raise InvalidValueError, <<~MSG
      fetch_or_raise was called with an invalid value.
      Expected one of: #{allowed_values.inspect}
      Got: #{given_value.inspect}
    MSG
  end
end

def fetch_or_raise_boolean(given_value)

TODO: use these two more
def fetch_or_raise_boolean(given_value)
  fetch_or_raise(TRUE_OR_FALSE, given_value)
end

def fetch_or_raise_integer(given_value)

def fetch_or_raise_integer(given_value)
  fetch_or_raise(INTEGER_TYPES, given_value, against: given_value.class.name)
end