<?php

###############################################################################
# godaddy.php
#
# @author Anil Kumar <akumar@codepunch.com>
# @link   https://codepunch.com
#
############################################################################### 

namespace CodePunch\LU\Registrars;

use Exception;
use CodePunch\Base\Util as UTIL;

###############################################################################

class GoDaddy extends RegistrarAPI {
	
	private $api_url_base  		= 'https://api.godaddy.com/v1/domains/';
	private $api_access_key		= null;
	private $api_secret_key		= null;
	private $api_shopper_id		= null;
	private $api_customer_info	= null;
	
	###########################################################################
	
	public function __construct($cm, $apikey, $apisecret, $shopper_id='')
	{ 
		parent::__construct($cm);
		$this->api_access_key = $apikey;
		$this->api_secret_key = $apisecret;
		$this->api_shopper_id = $shopper_id;
	}
	
	###########################################################################
	
	public static function getKeyNames()
	{
		return array('API Key', 'API Secret', 'Shopper ID (optional)');
	}
	
	###########################################################################
	
	public function supported() {
		return array('domainlist', 'whois', 'profileinfo');
	}
	
	###########################################################################
	
	private function construct_http_header()
	{
		return array("Authorization: sso-key $this->api_access_key:$this->api_secret_key");
	}
	
	###########################################################################
	
	private function construct_url($domain)
	{
		$url = $this->api_url_base . $domain;
		if($this->api_shopper_id && strlen($this->api_shopper_id) > 2)
			$url .= "?X-Shopper-Id=" . $this->api_shopper_id;
		return $url;
	}
	
	###########################################################################
	
	private function cleanup_keys(&$info)
	{
		$xlate = array(
		'contactRegistrantnameFirst' => 'Registrant First Name',
		'contactRegistrantnameLast' => 'Registrant Last Name',
		'contactRegistrantorganization' => 'Registrant Organization',
		'contactRegistrantemail' => 'Registrant Email',
		'contactRegistrantphone' => 'Registrant Phone',
		'contactRegistrantfax' => 'Registrant Fax',
		'contactRegistrantaddressMailingaddress1' => 'Registrant Address',
		'contactRegistrantaddressMailingaddress2' => 'Registrant Street',
		'contactRegistrantaddressMailingcity' => 'Registrant City',
		'contactRegistrantaddressMailingstate' => 'Registrant State',
		'contactRegistrantaddressMailingpostalCode' => 'Registrant ZIP',
		'contactRegistrantaddressMailingcountry' => 'Registrant Country',
		'contactBillingnameFirst' => 'Billing First Name',
		'contactBillingnameLast' => 'Billing Last Name',
		'contactBillingorganization' => 'Billing Organization',
		'contactBillingemail' => 'Billing Email',
		'contactBillingphone' => 'Billing Phone',
		'contactBillingfax' => 'Billing Fax',
		'contactBillingaddressMailingaddress1' => 'Billing Address',
		'contactBillingaddressMailingaddress2' => 'Billing Street',
		'contactBillingaddressMailingcity' => 'Billing City',
		'contactBillingaddressMailingstate' => 'Billing State',
		'contactBillingaddressMailingpostalCode' => 'Billing ZIP',
		'contactBillingaddressMailingcountry' => 'Billing Country',
		'contactAdminnameFirst' => 'Admin First Name',
		'contactAdminnameLast' => 'Admin Last Name',
		'contactAdminorganization' => 'Admin Organization',
		'contactAdminemail' => 'Admin Email',
		'contactAdminphone' => 'Admin Phone',
		'contactAdminfax' => 'Admin Fax',
		'contactAdminaddressMailingaddress1' => 'Admin Address',
		'contactAdminaddressMailingaddress2' => 'Admin Street',
		'contactAdminaddressMailingcity' => 'Admin City',
		'contactAdminaddressMailingstate' => 'Admin State',
		'contactAdminaddressMailingpostalCode' => 'Admin ZIP',
		'contactAdminaddressMailingcountry' => 'Admin Country',
		'contactTechnameFirst' => 'Tech First Name',
		'contactTechnameLast' => 'Tech Last Name',
		'contactTechorganization' => 'Tech Organization',
		'contactTechemail' => 'Tech Email',
		'contactTechphone' => 'Tech Phone',
		'contactTechfax' => 'Tech Fax',
		'contactTechaddressMailingaddress1' => 'Tech Address',
		'contactTechaddressMailingaddress2' => 'Tech Street',
		'contactTechaddressMailingcity' => 'Tech City',
		'contactTechaddressMailingstate' => 'Tech State',
		'contactTechaddressMailingpostalCode' => 'Tech ZIP',
		'contactTechaddressMailingcountry' => 'Tech Country',
		'expires' => 'Registrar Registration Expiration Date',
		'domainId' => 'Domain ID',
		'domain' => 'Domain',
		'status' => 'Status', 
		'expirationProtected' => 'Expiration Protected', 
		'holdRegistrar' => 'Registrar Hold',
		'locked' => 'Locked',
		'privacy' => 'Privacy',
		'renewAuto' => 'Auto Renew',
		'renewable' => 'Renewable',
		'renewDeadline' => 'Renew Deadline',
		'transferProtected' => 'Transfer Protected',
		'createdAt' => 'Creation Date',
		'nameServers0' => 'Name Server 0',
		'nameServers1' => 'Name Server 1',
		'nameServers2' => 'Name Server 2',
		'nameServers3' => 'Name Server 3',
		'nameServers4' => 'Name Server 4',
		'nameServers5' => 'Name Server 5',
		'nameServers6' => 'Name Server 6',
		'nameServers7' => 'Name Server 7',
		'nameServers8' => 'Name Server 8',
		);
		UTIL::array_xlate_keys($info, $xlate);
	}
	
	###########################################################################

	public function whois($domain)
	{
		$responce = array('status'=>false,'error'=>'','data'=>'');
		try {
			$url = $this->construct_url($domain);
			$header = $this->construct_http_header();
			$whois = UTIL::curl_get_url($url, 10, CURLAUTH_ANY, $header);
			$whois = $whois['result'];
			if($whois != "") {
				$whois = json_decode($whois, true);
				if(isset($whois['message'])) {
					if(strstr($whois['message'], "not found for shopper") !== false)
						$whois['message'] = "Domain is not present in your profile";
					throw new Exception($whois['message']);
				}
				else if(is_array($whois)) {
					$whois = UTIL::array_flatten($whois);
					unset($whois['authCode']);
					if(isset($whois['contactRegistrantnameFirst']))
						$registrant = $whois['contactRegistrantnameFirst'];
					if(isset($whois['contactRegistrantnameLast']))
						$registrant .= " " . $whois['contactRegistrantnameLast'];
					if(isset($registrant))
						$whois['Registrant Name'] = trim($registrant);
					$this->cleanup_keys($whois);
					if(isset($whois['code'])) {
						throw new Exception($whois['code']);
					}
					else
						$whois = UTIL::array_to_text($whois);
					$responce['data'] = $whois;
					$responce['status'] = true;
				}
			}
			else
				throw new Exception("Unable to connect to GoDaddy API server");
		}
		catch (Exception $e) {
			$responce['error'] = $e->getMessage();
		}
		return $responce;
	}
	
	###########################################################################

	public function isWorking()
	{
		$url = $this->api_url_base . "?statusGroups=VISIBLE&limit=1";
		if($this->api_shopper_id && strlen($this->api_shopper_id) > 2)
			$url .= "&X-Shopper-Id=" . $this->api_shopper_id;
		$header = $this->construct_http_header();
		$info = UTIL::curl_get_url($url, 10, CURLAUTH_ANY, $header);
		if(isset($info['status']) && $info['status'] == 200) {
			if($info['result'] != "") {
				$info = $info['result'];
				$info = json_decode($info, true);
				if(is_array($info) && count($info) == 1 && !isset($info['message']))
					return true;
				else if(isset($info['message']))
					return $info['message'];
				else
					return "Connected, no data";
			}
		}
		else if (isset($info['result'])) {
			if($info['result'] != "") {
				$info = json_decode($info['result'], true);
				if(isset($info['message']))
					return $info['message'];
			}
		}
		return "Unable to connect";
	}

	###########################################################################
	
	public function domainlist(?callable $callback=null)
	{
		$domains = array();
		
		$count = 1000;
		$lastdomain = "";
		while(1) {
			$thisdata = array();
			$added = 0;
			$url = $this->api_url_base . "?statusGroups=VISIBLE&limit={$count}&marker={$lastdomain}";
			if($this->api_shopper_id && strlen($this->api_shopper_id) > 2)
				$url .= "&X-Shopper-Id=" . $this->api_shopper_id;
			$header = $this->construct_http_header();
			$info = UTIL::curl_get_url($url, 10, CURLAUTH_ANY, $header);
			$info = $info['result'];
			$info = json_decode($info, true);
			if(isset($info[0]['domain'])) {
				foreach($info as $d) {
					$domain = $d['domain'];
					$thisdata[] = $domain;
					$lastdomain = $domain;
					$added++;
				}
			}
			else if(isset($info['message'])) {
				throw new Exception($info['message']);
			}
			if(!$added || $lastdomain == "")
				break;
			
			if($callback != null) {
				$status = call_user_func($callback, $lastdomain, count($domains), $thisdata);
				if($status == self::REGAPI_STOP)
					break;
			}
			if(count($thisdata))
				$domains = array_merge($domains, $thisdata);
			if($added < $count)
				break;
		}
		return $domains;
	}
	
	###########################################################################
	/*
		// Sample Code
		$auth = new \CodePunch\Config\Auth(\CodePunch\DB\Database::READONLY_TABLES);
		if($auth) {
			$db = $auth->getDatabase();
			$luManager = new \CodePunch\LU\LookupManager($auth);
			$ci = $auth->getDatabase()->getRegistrarAPIClass("GODADDY", $auth);
			if($ci['class'] != "" && count($ci['params'])) {
				$regapi = new $ci['class']($luManager, ...$ci['params']);
				
				$r = $regapi->profileinfo();
				print_r($r);
				$r = $regapi->profileinfo();
				print_r($r);
				
				$customerid = $r['data']['customerId'];
				$r = $regapi->getDomainInfo("domainpunch.in");
				print_r($r);
			}
			if($db) {
				UTIL::print("OK");
			}
		}
	*/
	
	public function profileinfo() {
		$responce = array('status'=>false,'error'=>'','data'=>'', 'source'=>'');
		if($this->api_customer_info) {
			$responce['data'] = $this->api_customer_info;
			$responce['status'] = true;
			$responce['source'] = 'cache';
		}
		else {
			$shopperid = $this->api_shopper_id;
			if(!$shopperid)
				$responce['error'] = "Missing shopper id. Please create a new GoDaddy profile that includes the shopper-id.";
			else {
				try {
					$url = 'https://api.godaddy.com/v1/shoppers/' . $shopperid . '?includes=customerId';
					$header = $this->construct_http_header();
					$info = UTIL::curl_get_url($url, 10, CURLAUTH_ANY, $header);
					if(isset($info['status']) && $info['status'] == 200) {
						if($info['result'] != "") {
							$responce['status'] = true;
							$this->api_customer_info = json_decode($info['result'], true);
							$responce['data'] = $this->api_customer_info;
						}
					}
					else if (isset($info['result'])) {
						if($info['result'] != "") {
							$info = json_decode($info['result'], true);
							if(isset($info['message']))
								$responce['error'] = $info['message'];
						}
					}
				}
				catch (Exception $e) {
					$responce['error'] = $e->getMessage();
				}
			}
		}
		return $responce;
	}
	
	###########################################################################
	
	public function getDomainInfo($domain) {
		$responce = array('status'=>false,'error'=>'','data'=>'');
		$ci = $this->profileinfo();
		if($ci['status']) {
			try {
				$customerid = $ci['data']['customerId'];
				$url = 'https://api.godaddy.com/v2/customers/' . $customerid . '/domains/' . $domain;
				$header = $this->construct_http_header();
				$info = UTIL::curl_get_url($url, 10, CURLAUTH_ANY, $header);
				if(isset($info['status']) && $info['status'] == 200) {
					$responce['status'] = true;
					$info = json_decode($info['result'], true);
					$responce['data'] = $info;
				}
				else if (isset($info['result'])) {
					if($info['result'] != "") {
						$info = json_decode($info['result'], true);
						if(isset($info['message']))
							$responce['error'] = $info['message'];
					}
				}
			}
			catch (Exception $e) {
				$responce['error'] = $e->getMessage();
			}
		}
		else {
			$responce['error'] = $ci['error'];
		}
		return $responce;
	}
}

###############################################################################

?>