class Compliance::API

everything will be stored in local Configuration store
API Implementation does not hold any state by itself,

def self.exist?(config, profile)

verifies that a profile
def self.exist?(config, profile)
  _msg, profiles = Compliance::API.profiles(config)
  if !profiles.empty?
    index = profiles.index { |p| "#{p[:org]}/#{p[:name]}" == profile }
    !index.nil? && index >= 0
  else
    false
  end
end

def self.get_token_via_password(url, username, password, insecure)

Use username and password to get an API access token
def self.get_token_via_password(url, username, password, insecure)
  uri = URI.parse("#{url}/login")
  req = Net::HTTP::Post.new(uri.path)
  req.body = { userid: username, password: password }.to_json
  access_token = nil
  response = Compliance::HTTP.send_request(uri, req, insecure)
  data = response.body
  if response.code == '200'
    access_token = data
    msg = 'Successfully fetched an API access token valid for 12 hours'
    success = true
  else
    success = false
    msg = "Failed to authenticate to #{url} \n\
sponse code: #{response.code}\n  Body: #{response.body}"
  end
  [success, msg, access_token]
end

def self.get_token_via_refresh_token(url, refresh_token, insecure)

Use username and refresh_toke to get an API access token
def self.get_token_via_refresh_token(url, refresh_token, insecure)
  uri = URI.parse("#{url}/login")
  req = Net::HTTP::Post.new(uri.path)
  req.body = { token: refresh_token }.to_json
  access_token = nil
  response = Compliance::HTTP.send_request(uri, req, insecure)
  data = response.body
  if response.code == '200'
    begin
      tokendata = JSON.parse(data)
      access_token = tokendata['access_token']
      msg = 'Successfully fetched API access token'
      success = true
    rescue JSON::ParserError => e
      success = false
      msg = e.message
    end
  else
    success = false
    msg = "Failed to authenticate to #{url} \n\
sponse code: #{response.code}\n  Body: #{response.body}"
  end
  [success, msg, access_token]
end

def self.profiles(config)

return all compliance profiles available for the user
def self.profiles(config)
  url = "#{config['server']}/user/compliance"
  # TODO, api should not be dependent on .supported?
  response = Compliance::HTTP.get(url, config['token'], config['insecure'], !config.supported?(:oidc))
  data = response.body
  response_code = response.code
  case response_code
  when '200'
    msg = 'success'
    profiles = JSON.parse(data)
    # iterate over profiles
    mapped_profiles = profiles.map do |owner, ps|
      ps.keys.map do |name|
        { org: owner, name: name }
      end
    end.flatten
    return msg, mapped_profiles
  when '401'
    msg = '401 Unauthorized. Please check your token.'
    return msg, []
  else
    msg = "An unexpected error occurred (HTTP #{response_code}): #{response.message}"
    return msg, []
  end
end

def self.upload(config, owner, profile_name, archive_path)

def self.upload(config, owner, profile_name, archive_path)
  # upload the tar to Chef Compliance
  url = "#{config['server']}/owners/#{owner}/compliance/#{profile_name}/tar"
  res = Compliance::HTTP.post_file(url, config['token'], archive_path, config['insecure'], !config.supported?(:oidc))
  [res.is_a?(Net::HTTPSuccess), res.body]
end

def self.version(url, insecure)

it before we know the version (e.g. oidc or not)
NB this method does not use Compliance::Configuration to allow for using
return the server api version
def self.version(url, insecure)
  if url.nil?
    puts "
er configuration information is missing.
se login using `inspec compliance login https://compliance.test --user admin --insecure --token 'PASTE TOKEN HERE' `
  else
    response = Compliance::HTTP.get(url+'/version', nil, insecure)
    data = response.body
  end
  if !data.nil?
    JSON.parse(data)
  else
    {}
  end
end