class Trace::ClientService < ApplicationService

  def post(url, params={})
    puts "[trace][POST] request params: #{params}"
    conn.post(full_url(url), params[:data]) 
  end

  def authed_post(token, url, params={})
    puts "[trace][POST] request params: #{params}"
    puts "[trace][POST] request token: #{token}"
    conn.post do |req|
      req.url full_url(url, 'post')
      req.headers['Authorization'] = token
      req.body = params[:data].as_json
    end
  end

  def http_authed_post(token, url, params={})
    puts "[trace][POST] request params: #{params}"
    puts "[trace][POST] request token: #{token}"
    url = URI("#{full_url(url)}")
    http = Net::HTTP.new(url.host, url.port)
    http.read_timeout = 1200
    request = Net::HTTP::Post.new(url)
    request["Authorization"] = token
    form_data = params[:data].stringify_keys.to_a
    request.set_form form_data, 'multipart/form-data'
    http.request(request)
  end

  def get(url, params={})
    puts "[trace][GET] request params: #{params}"
    conn.get do |req|
      req.url full_url(url, 'get')
      params.each_pair do |key, value|
        req.params["#{key}"] = value
      end
    end
  end

  def authed_get(token, url, params={})
    puts "[trace][GET] request params: #{params}"
    puts "[trace][GET] request token: #{token}"
    conn.get do |req|
      req.url full_url(url, 'get')
      params.each_pair do |key, value|
        req.params["#{key}"] = value
      end
      req.headers['Authorization'] = token
    end
  end

  def delete(url, params={})
    puts "[trace][DELETE] request params: #{params}"
    conn.delete(full_url(url), params[:data])
  end

  def authed_delete(token, url, params={})
    puts "[trace][DELETE] request params: #{params}"
    puts "[trace][DELETE] request token: #{token}"
    conn.delete do |req|
      req.url full_url(url, 'delete')
      req.headers['Authorization'] = token
      req.body = params[:data].as_json
    end
  end

  def patch(url, params={})
    puts "[trace][PATCH] request params: #{params}"
    conn.patch(full_url(url), params[:data])
  end

  def authed_patch(token, url, params={})
    puts "[trace][PATCH] request params: #{params}"
    puts "[trace][PATCH] request token: #{token}"
    conn.patch do |req|
      req.url full_url(url, 'patch')
      req.headers['Authorization'] = token
      req.body = params[:data].as_json
    end
  end

  def put(url, params={})
    puts "[trace][PUT] request params: #{params}"
    conn.put(full_url(url), params[:data])
  end

  def authed_put(token, url, params={})
    puts "[trace][PUT] request params: #{params}"
    puts "[trace][PUT] request token: #{token}"
    conn.put do |req|
      req.url full_url(url, 'put')
      req.headers['Authorization'] = token
      req.body = params[:data].as_json
    end
  end

  def conn 
    Faraday.new(url: domain)
  end

  def base_url 
    Trace.trace_config[:base_url]
  end

  def domain
    Trace.trace_config[:domain]
  end

  def api_url
    [domain, base_url].join('')
  end

  def full_url(api_rest, action='post')
    url = [api_url, api_rest].join('').freeze
    url = action === 'get' ? url : URI.escape(url)
    url = URI.escape(url) unless url.ascii_only?
    puts "[trace] request url: #{url}"
    return url
  end
  
  def log_error(status, body)
    puts "[trace] status:  #{status}"
    puts "[trace] body:    #{body}"
  end

  def render_response(response)
    if response.is_a?(Faraday::Response) 
      status = response.status
      body = JSON.parse(response&.body)

      log_error(status, body)

      return [body["code"], body["data"], body["error"]]
    end
     
    if response.is_a?(Net::HTTPOK)
      status = 200
      body = JSON.parse(response&.body)
  
      log_error(status, body)
  
      return [body["code"], body["data"], body["error"]]
    end 
  end
end