require_relative "coinpayments/version"
require_relative "coinpayments/configuration"
require "httparty"

# ================================================
# COINPAYMENTS ===================================
# ================================================
module Coinpayments

  # ----------------------------------------------
  # SELF -----------------------------------------
  # ----------------------------------------------
  class << self
    attr_accessor :configuration
  end

  # ==============================================
  # PUBLIC =======================================
  # ==============================================
  public

  # ----------------------------------------------
  # CONFIGURE ------------------------------------
  # ----------------------------------------------
  def self.configure
    yield(configuration) if block_given?
  end

  # ==============================================
  # PRIVATE ======================================
  # ==============================================
  private

  # ----------------------------------------------
  # CONFIGURATION --------------------------------
  # ----------------------------------------------
  def self.configuration
    @configuration ||=  Configuration.new
  end

  # ----------------------------------------------
  # REQUIRED-PARAMS ------------------------------
  # ----------------------------------------------
  def self.required_params
    { version: configuration.version, key: configuration.public_api_key }
  end

  # ----------------------------------------------
  # HMAC -----------------------------------------
  # ----------------------------------------------
  def self.hmac(body)
    OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha512'), configuration.private_api_key, HTTParty::HashConversions.to_params(body))
  end

  # ----------------------------------------------
  # API-CALL -------------------------------------
  # ----------------------------------------------
  def self.api_call(args)
    body = required_params.merge!(cmd: caller[0][/`.*'/][1..-2]).merge!(args)
    response = HTTParty.post(configuration.base_uri, body: body, headers: {'hmac' => hmac(body)})
    response['error'] == 'ok' ? response['result'] : response['error']
  end

  # ==============================================
  # PUBLIC =======================================
  # ==============================================
  public

  # INFORMATIONAL COMMANDS
  # ----------------------------------------------

  # ----------------------------------------------
  # ACCOUNT-INFO ---------------------------------
  # ----------------------------------------------
  def self.get_basic_info
    api_call(nil)
  end

  # ----------------------------------------------
  # RATES ----------------------------------------
  # ----------------------------------------------
  def self.rates(options = {})
    api_call(options)
  end


  # RECEIVING PAYMENTS
  # ----------------------------------------------

  # ----------------------------------------------
  # CREATE-TRANSACTION ---------------------------
  # ----------------------------------------------
  def self.create_transaction(amount, currency1, currency2, options = {})
    args = { amount: amount, currency1: currency1, currency2: currency2 }.merge!(options)
    api_call(args)
  end

  # ----------------------------------------------
  # GET-CALLBACK-ADDRESS -------------------------
  # ----------------------------------------------
  def self.get_callback_address(currency, options = {})
    args = { currency: currency }.merge!(options)
    api_call(args)
  end

  # ----------------------------------------------
  # GET-TX-INFO ----------------------------------
  # ----------------------------------------------
  def self.get_tx_info(txid)
    args = { txid: txid }
    api_call(args)
  end

  # ----------------------------------------------
  # GET-TX-IDS -----------------------------------
  # ----------------------------------------------
  def self.get_tx_ids(options = {})
    api_call(options)
  end


  # WALLET
  # ----------------------------------------------

  # ----------------------------------------------
  # BALANCES -------------------------------------
  # ----------------------------------------------
  def self.balances(options = {})
    api_call(options)
  end

  # ----------------------------------------------
  # CREATE-WITHDRAWAL ----------------------------
  # ----------------------------------------------
  def self.create_withdrawal(amount, currency, address, options = {})
    args = { amount: amount, currency: currency, address: address }.merge!(options)
    api_call(args)
  end

  # ----------------------------------------------
  # CREATE-MASS-WITHDRAWAL -----------------------
  # ----------------------------------------------
  def self.create_mass_withdrawal(withdrawals)
    api_call(withdrawals)
  end

  # ----------------------------------------------
  # GET-WITHDRAWAL-INFO --------------------------
  # ----------------------------------------------
  def self.get_withdrawal_info(id)
    args = { id: id }
    api_call(args)
  end


  # SIGNATURES
  # ----------------------------------------------

  # ----------------------------------------------
  # SIGN -----------------------------------------
  # ----------------------------------------------
  def self.sign(callback_body)
    OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha512'), configuration.secret_phrase,callback_body)
  end

end
