<?php

namespace App\Libraries\Adapter\API;

// 참고:
// https://techhub.hpe.com/eginfolib/servers/docs/HPRestfultool/iLo4/data_model_reference.html
// https://github.com/SyntaxPhoenix/iloclient
class CurlAPI extends API
{
	public function __construct($debug = false)
	{
		parent::__construct($debug);
	}
	private function debugging($response)
	{
		if (!$this->_debug) {
			return false;
		}
		if ($response === false) {
			log_message('error', curl_error($this->getChannel()));
		}
		$info = curl_getinfo($this->getChannel());
		log_message('debug', var_export($info, true));
		log_message('debug', var_export($this->getDatas(), true));
		log_message('debug', "{$info['total_time']}초, url:{$info['url']}, return:{$info['http_code']}");
		switch ($info['http_code']) {
			case 100:
				log_message('debug', "{$info['http_code']} Continue");
				break;
			case 101:
				log_message('debug', "{$info['http_code']} Switching Protocols");
				break;
			case 200:
				log_message('debug', "{$info['http_code']} OK");
				break;
			case 201:
				log_message('debug', "{$info['http_code']} Created");
				break;
			case 202:
				log_message('debug', "{$info['http_code']} Accepted");
				break;
			case 203:
				log_message('debug', "{$info['http_code']} Non-Authoritative Information");
				break;
			case 204:
				log_message('debug', "{$info['http_code']} No Content");
				break;
			case 205:
				log_message('debug', "{$info['http_code']} Reset Content");
				break;
			case 206:
				log_message('debug', "{$info['http_code']} Partial Content");
				break;
			case 300:
				log_message('debug', "{$info['http_code']} Multiple Choices");
				break;
			case 301:
				log_message('debug', "{$info['http_code']} Moved Permanently");
				break;
			case 302:
				log_message('debug', "{$info['http_code']} Found");
				break;
			case 303:
				log_message('debug', "{$info['http_code']} See Other");
				break;
			case 304:
				log_message('debug', "{$info['http_code']} Not Modified");
				break;
			case 305:
				log_message('debug', "{$info['http_code']} Use Proxy");
				break;
			case 306:
				log_message('debug', "{$info['http_code']} (Unused)");
				break;
			case 307:
				log_message('debug', "{$info['http_code']} Temporary Redirect");
				break;
			case 400:
				log_message('debug', "{$info['http_code']} Bad Request");
				break;
			case 401:
				log_message('debug', "{$info['http_code']} Unauthorized");
				break;
			case 402:
				log_message('debug', "{$info['http_code']} Payment Required");
				break;
			case 403:
				log_message('debug', "{$info['http_code']} Forbidden");
				break;
			case 404:
				log_message('debug', "{$info['http_code']} Not Found");
				break;
			case 405:
				log_message('debug', "{$info['http_code']} Method Not Allowed");
				break;
			case 406:
				log_message('debug', "{$info['http_code']} Not Acceptable");
				break;
			case 407:
				log_message('debug', "{$info['http_code']} Proxy Authentication Required");
				break;
			case 408:
				log_message('debug', "{$info['http_code']} Request Timeout");
				break;
			case 409:
				log_message('debug', "{$info['http_code']} Conflict");
				break;
			case 410:
				log_message('debug', "{$info['http_code']} Gone");
				break;
			case 411:
				log_message('debug', "{$info['http_code']} Length Required");
				break;
			case 412:
				log_message('debug', "{$info['http_code']} Precondition Failed");
				break;
			case 413:
				log_message('debug', "{$info['http_code']} Request Entity Too Large");
				break;
			case 414:
				log_message('debug', "{$info['http_code']} Request-URI Too Long");
				break;
			case 415:
				log_message('debug', "{$info['http_code']} Unsupported Media Type");
				break;
			case 416:
				log_message('debug', "{$info['http_code']} Requested Range Not Satisfiable");
				break;
			case 417:
				log_message('debug', "{$info['http_code']} Expectation Failed");
				break;
			case 500:
				log_message('debug', "{$info['http_code']} Internal Server Error");
				break;
			case 501:
				log_message('debug', "{$info['http_code']} Not Implemented");
				break;
			case 502:
				log_message('debug', "{$info['http_code']} Bad Gateway");
				break;
			case 503:
				log_message('debug', "{$info['http_code']} Service Unavailable");
				break;
			case 504:
				log_message('debug', "{$info['http_code']} Gateway Timeout");
				break;
			case 505:
				log_message('debug', "{$info['http_code']} HTTP Version Not Supported");
				break;
			default:
				log_message('debug', "Return Code : {$info['http_code']}");
				break;
		}
	}
	protected function getChannel()
	{
		if (is_null($this->_channel)) {
			$this->_channel = curl_init();
		}
		return $this->_channel;
	}
	public function setSSLVerifay()
	{
		//SSL 확인여부용
		curl_setopt($this->getChannel(), CURLOPT_SSL_VERIFYPEER, API['SSL_VERIFY']);
		curl_setopt($this->getChannel(), CURLOPT_SSL_VERIFYHOST, API['SSL_VERIFY']);
	}
	public function setCookie()
	{
		//cookie값 전달용
		foreach (curl_getinfo($this->getChannel(), CURLINFO_COOKIELIST) as $cookie_line) {
			curl_setopt($this->getChannel(), CURLOPT_COOKIELIST, $cookie_line);
		}
	}
	public function setAUthentication()
	{
		//접속인증 정보값 전달용
		curl_setopt($this->getChannel(), CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
		curl_setopt($this->getChannel(), CURLOPT_USERPWD, implode(":", $this->getAccountInfo()));
	}
	protected function execute_process(): object
	{
		curl_setopt($this->getChannel(), CURLOPT_URL, $this->getServerInfo() . $this->getURL());
		switch ($this->getMethod()) {
			case 'POST':
				curl_setopt($this->getChannel(), CURLOPT_POST, TRUE);
				curl_setopt($this->getChannel(), CURLOPT_CUSTOMREQUEST, 'PATCH');
				//cookie값 파일저장용
				curl_setopt($this->getChannel(), CURLOPT_COOKIEJAR, API['COOKIE_FILE']);
				curl_setopt($this->getChannel(), CURLOPT_COOKIEFILE, API['COOKIE_FILE']);
				break;
			default:
				curl_setopt($this->getChannel(), CURLOPT_POST, false);
				break;
		}
		curl_setopt($this->getChannel(), CURLOPT_POSTFIELDS, json_encode($this->getDatas(), true));
		curl_setopt($this->getChannel(), CURLOPT_RETURNTRANSFER, true);
		curl_setopt($this->getChannel(), CURLOPT_CONNECTTIMEOUT, 3);
		curl_setopt($this->getChannel(), CURLOPT_TIMEOUT, 20);
		curl_setopt($this->getChannel(), CURLOPT_HTTPHEADER, $this->getHeaders());
		$response = curl_exec($this->getChannel());
		$this->debugging($response);
		curl_close($this->getChannel());
		if (is_null($response)) {
			throw new \Exception("해당서버[{$this->getServerInfo()}]의 ILO접속 오류가 발생하였습니다.");
		}
		return json_decode($response);
	}
}
