<?php
namespace TronTool;

use GuzzleHttp\Client;

class NodeClient{
  protected $client;
  protected $headers = [];
  
  static function mainNet(){
    return new self('https://api.trongrid.io');
  }
  
  static function testNet(){
    return new self('https://api.shasta.trongrid.io');
  }
  
  function __construct($uri){
    $apiKey = '';
    if (function_exists('config')) {
      $apiKey = \config('app.tron_pro_api_key', '');
    }
    if (!$apiKey) {
      $apiKey = getenv('TRON_PRO_API_KEY') ?: '';
    }
    if ($apiKey) {
      $this->headers['TRON-PRO-API-KEY'] = $apiKey;
    }

    $opts = [
      'base_uri' => $uri,
      'verify' => false,
      'headers' => $this->headers,
    ];
    $this->client = new Client($opts);
  }
  
  function post($api,$payload=[]){
    $opts = [
      'json' => $payload,
      'headers' => $this->headers,
    ];
    $rsp = $this->requestWithRetry('post',$api,$opts);
    return $this->handle($rsp);
  }
  
  function get($api,$query=[]){
    $opts = [
      'query' => $query,
      'headers' => $this->headers,
    ];
    $rsp = $this->requestWithRetry('get',$api,$opts);
    return $this->handle($rsp);
  }

  protected function requestWithRetry($method,$api,$opts=[],$maxRetries=1){
    $attempt = 0;
    start:
    try {
      return $this->client->{$method}($api,$opts);
    } catch (\Throwable $e) {
      $attempt++;
      if ($attempt <= $maxRetries && strpos($e->getMessage(), '429') !== false) {
        usleep(5500000);
        goto start;
      }
      throw $e;
    }
  }
  
  function handle($rsp){
    $content = $rsp->getBody();
    //echo $content . PHP_EOL;
    return json_decode($content);
  }
  
  function version(){
    return '1.0.0';
  }
}