<?php
/*
 * Copyright (c) 2024 by Legiteum, Inc. Permission to use subject to terms below.
 *
 * Do not modify this module and then redistribute it to others under the same name. Otherwise, feel
 * free to use it any way you wish.
 * 
 * Version: 1.0.2 / 2025-05-11
 *
 * The Haypenny HBlock API implementation in PHP.
 *
 */

class HBlock {
	public static $txServerUrlStem = "https://tx.haypenny.net/";				// default is live production server

	public string $text;
	public string $realm;
	public int $balance;
	public float $usdBalance;

	public int $amount;			// amount actually debited in a combine operation

	public int $secretUsed;

	public string $errorCode;
	public string $errorMessage;

	public function __construct($blockString=null, $realm="apenny") {
		$this->text = $blockString;
		$this->realm = $realm;
		$this->balance = 0;
		$this->usdBalance = 0.0;

		$this->secretUsed = 0;

		$this->errorCode = "";
		$this->errorMessage = "";
	}

	public function info() : bool {
		if($this->_call("Info", "block=" . $this->text, $returnObject)){
			$this->balance = $returnObject->balance;
			$this->usdBalance = $returnObject->usd_balance;
			$this->realm = $returnObject->coin_id;

			return true;
		}
		else {
			return false;
		}
	}

	public function split(HBlock &$newBlock, string $amount = ""): bool {
		if(!($this->_genSecret()))return false;

		$params = "block=" . $this->text . "&secret=" . $this->secretUsed . "coin_id=" . $this->realm;

		if($amount != ""){
			$params .= "&amount=" . $amount;
		}

		if($this->_call("Split", $params, $returnObject)){
			$this->balance = $returnObject->balance;
			$this->usdBalance = $returnObject->usd_balance;

			$newBlock = new HBlock($returnObject->new_block, $this->realm);
			$newBlock->balance = $returnObject->new_block_balance;
			$newBlock->usdBalance = $returnObject->new_block_usd_balance;

			return true;
		}
		else {
			return false;
		}
	}

	public function combine(string $blockString, string $amount = ""): bool {
		if(!($this->_genSecret()))return false;

		$params = "block=" . $blockString . "&secret=" . $this->secretUsed . "&combine_block=" . $this->text;

		if($amount != ""){
			$params .= "&amount=" . $amount;
		}

		if($this->_call("Combine", $params, $returnObject)){
			$this->balance = $returnObject->balance;
			$this->usdBalance = $returnObject->usd_balance;
			$this->amount = $returnObject->amount;
			return true;
		}
		else {
			return false;
		}
	}


	public static function setServer($systemName) {
		if($systemName === "SANDBOX"){
			HBlock::$txServerUrlStem = "https://sbtx.haypenny.com/";		// sandbox system
		}
		else if($systemName === "LIVE"){
			HBlock::$txServerUrlStem = "https://tx.haypenny.com/";			// live production
		}
		else {
			HBlock::$txServerUrlStem = $systemName;							// for internal testing
		}
	}

	private function _call(string $name, string $params, &$returnObject): bool {
		$str = file_get_contents(HBlock::$txServerUrlStem . "api/" . $name . "?" . $params);

		if($str === false){
			$this->errorCode = "network_error";
			$this->errorMessage = "There was a network error on the server call.";
			return false;
		}

		$obj = json_decode($str);

		if((!(is_array($obj))) && property_exists($obj, "error") && $obj->error) {
			$this->errorCode = $obj->name;
			$this->errorMessage = $obj->message;
			return false;
		}
		else {
			$returnObject = $obj;
			return true;
		}
	}

	private function _genSecret() : bool {
		try {
			$this->secretUsed = random_int(0, PHP_INT_MAX);
			return true;
		} catch (Exception $e) {
			$this->errorCode = "random_error";
			$this->errorMessage = "There was problem generating the random number for secret.";
			return false;
		}
	}
}


?>