#!/usr/bin/env ruby

require 'optparse'
require 'unleash'
require 'unleash/client'
require 'unleash/context'

options = {
  variant: false,
  verbose: false,
  quiet: false,
  url: 'http://localhost:4242',
  demo: false,
  disable_metrics: true,
  custom_http_headers: {},
  sleep: 0.1
}

OptionParser.new do |opts|
  opts.banner = "Usage: #{__FILE__} [options] feature [contextKey1=val1] [contextKey2=val2] \n\n" \
  "Where contextKey1 could be user_id, session_id, remote_address or any field in the Context class (or any property within it).\n"

  opts.on("-V", "--variant", "Fetch variant for feature") do |v|
    options[:variant] = v
  end

  opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
    options[:verbose] = v
  end

  opts.on("-q", "--quiet", "Quiet mode, minimum output only") do |v|
    options[:quiet] = v
  end

  opts.on("-uURL", "--url=URL", "URL base for the Unleash feature toggle service") do |u|
    options[:url] = u
  end

  opts.on("-d", "--demo", "Demo load by looping, instead of a simple lookup") do |d|
    options[:demo] = d
  end

  opts.on("-m", "--[no-]metrics", "Enable metrics reporting") do |m|
    options[:disable_metrics] = !m
  end

  opts.on("-sSLEEP", "--sleep=SLEEP", Float, "Sleep interval between checks (seconds) in demo") do |s|
    options[:sleep] = s
  end

  opts.on("-H", "--http-headers='Authorization: *:developement.secretstring'",
          "Adds http headers to all requests on the unleash server. Use multiple times for multiple headers.") do |h|
    http_header_as_hash = [h].to_h{ |l| l.split(": ") }.transform_keys(&:to_sym)

    options[:custom_http_headers].merge!(http_header_as_hash)
  end

  opts.on("-h", "--help", "Prints this help") do
    puts opts
    exit
  end
end.parse!

feature_name = ARGV.shift
raise 'feature_name is required. see --help for usage.' unless feature_name

options[:verbose] = false if options[:quiet]

log_level = \
  if options[:quiet]
    Logger::ERROR
  elsif options[:verbose]
    Logger::DEBUG
  else
    Logger::WARN
  end

@unleash = Unleash::Client.new(
  url: options[:url],
  app_name: 'unleash-ruby-sdk-cli',
  disable_metrics: options[:metrics],
  custom_http_headers: options[:custom_http_headers],
  log_level: log_level
)

context_params = ARGV.to_h{ |l| l.split("=") }.transform_keys(&:to_sym)
context_properties = context_params.reject{ |k, _v| [:user_id, :session_id, :remote_address].include? k }
context_params.select!{ |k, _v| [:user_id, :session_id, :remote_address].include? k }
context_params.merge!(properties: context_properties) unless context_properties.nil?
unleash_context = Unleash::Context.new(context_params)

if options[:verbose]
  puts "Running configuration:"
  p options
  puts "feature: #{feature_name}"
  puts "context_args: #{ARGV}"
  puts "context_params: #{context_params}"
  puts "context: #{unleash_context}"
  puts ""
end

if options[:demo]
  loop do
    enabled = @unleash.is_enabled?(feature_name, unleash_context)
    print enabled ? '.' : '|'
    sleep options[:sleep]
  end
elsif options[:variant]
  variant = @unleash.get_variant(feature_name, unleash_context)
  puts " For feature '#{feature_name}' got variant '#{variant}'"
else
  if @unleash.is_enabled?(feature_name, unleash_context)
    puts " '#{feature_name}' is enabled according to unleash"
  else
    puts " '#{feature_name}' is disabled according to unleash"
  end
end

@unleash.shutdown
