<?php

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

namespace CodePunch\LU\Registrars;

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

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

class DNSMadeEasy extends RegistrarAPI {
	
	private $api_url_base  		= 'https://api.dnsmadeeasy.com/V2.0/';
	private $api_api_key		= null;
	private $api_secret_key		= null;
	
	###########################################################################
	
	public function __construct($cm, $apikey, $secretkey)
	{ 
		parent::__construct($cm);
		$this->api_api_key = $apikey;
		$this->api_secret_key = $secretkey;
	}
	
	###########################################################################
	
	public function supported() {
		return array('domainlist', 'axfr');
	}
	
	###############################################################################

	private function request_headers()
	{
		$requestDate = gmdate('r', time());
		return array(
			"x-dnsme-apiKey: " . $this->api_api_key,
			"x-dnsme-requestDate: $requestDate",
			"x-dnsme-hmac: " . hash_hmac('sha1', $requestDate, $this->api_secret_key),
			'Content-Type: application/json',
		);
	}
	
	###############################################################################
	
	private function get_data($operation, $timeout=10)
	{
		$url = $this->api_url_base . $operation;
		$retv = UTIL::curl_get_url($url, $timeout, CURLAUTH_ANY, $this->request_headers());
		$retv['result'] = ($retv['result'] === false) ? "" : $retv['result'];
		
		$records = array();
		if($retv['status'] == 200) {
			$data = (array)json_decode($retv['result']);
			if(isset($data['data'])) {
				foreach($data['data'] as $record) {
					$records[] = (array)$record;
				}
			}
			else
				$records = (array)$data;
		}
		else {
			UTIL::debug_cli_print($retv);
			throw new Exception($retv['error']);
		}
		return $records;
	}

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

	public function isWorking()
	{
		$operation = "dns/transferAcl";
		$timeout = 20;
		$url = $this->api_url_base . $operation;
		$retv = UTIL::curl_get_url($url, $timeout, CURLAUTH_ANY, $this->request_headers());
		if($retv['status'] == 200)
			return true;
		else {
			if($retv['result'] !== false && $retv['result'] != "") {
				$data = (array)json_decode($retv['result']);
				if(!isset($data) || !count($data))
					return "Unable to connect";
				else if(is_array($data['error']))
					return $data['error'][0];
				else
					return $data['error'];
			}
		}
		return "Unable to connect";
	}
		
	###########################################################################
	
	public function domainlist(callable $callback=null)
	{
		$hostnames = array();
		$records = $this->get_data("dns/managed/", 20);
		$requestcount = 1;
		$index = 0;
		foreach($records as $r) {
			$did = $r['id'];
			$axfrip = "";
			$dinfo = $this->get_data("dns/managed/$did", 20);
			if(isset($dinfo['axfrServer'])) {
				$axfrinfo = (array)$dinfo['axfrServer'];
				$axfrip = UTIL::get_from_array($axfrinfo['ipv4'], "");
			}
			$domain = $r['name'];
			$thisdata = array();
			$thisdata[] = array('domain'=>$domain, 'import_row_id'=>$did, 'axfr_ip'=>$axfrip);
			$txtrecords = array();
			$types = array('CNAME', 'A', 'TXT');
			foreach($types as $type) {
				$irecords = $this->get_data("dns/managed/$did/records?type=$type", 20);
				$requestcount++;
				foreach($irecords as $ir) {
					$name = $ir['name'];
					if($name != "") {
						if(strcasecmp($ir['type'], "txt"))
							$thisdata[] = "$name.$domain";
						else
							$txtrecords[] = $name;
					}
				}
				sleep(3);
			}
			if($callback != null) {
				$status = call_user_func($callback, $domain, $index, $thisdata);
				if($status == self::REGAPI_STOP)
					break;
				
				// We will add the TXT records directly. These are stored 
				// as subdomains but with SD_TXT_ROWS flag
				// TXT records should not be checked for SSL, only DNS
				if(count($txtrecords)) {
					$auth = $this->getConnectionManager()->getAuthentication();
					$db = $auth->getDatabase();
					$sid = $db->getDomainID($domain);
					if($sid !== false && $sid >= 0) {
						foreach($txtrecords as $tr) {
							$db->addTXTName($sid, $tr);
						}
					}
				}
			}
			if(count($thisdata))
				$hostnames = array_merge($hostnames, $thisdata);
			$index++;
		}
		return $hostnames;
	}
	
	###############################################################################
	
	private function put_data($operation, $postdata, $timeout=10)
	{
		$url = $this->api_url_base . $operation;
		$retv = UTIL::curl_put_url($url, $timeout, CURLAUTH_ANY, $this->request_headers(), $postdata);
		$retv['result'] = ($retv['result'] === false) ? "" : $retv['result'];
		return $retv;
	}
	
	###############################################################################
	
	private function post_data($operation, $postdata, $timeout=10)
	{
		$url = $this->api_url_base . $operation;
		$retv = UTIL::curl_post_url($url, $timeout, CURLAUTH_ANY, $this->request_headers(), $postdata);
		$retv['result'] = ($retv['result'] === false) ? "" : $retv['result'];
		return $retv;
	}
	
	###########################################################################
	
	public function get_acl_list()
	{
		$op = "dns/transferAcl";
		$records = $this->get_data($op, 20);
		return $records;
	}
	
	###########################################################################
	
	public function create_acl($name)
	{
		$acls = $this->get_acl_list();
		foreach($acls as $acl) {
			$aname = UTIL::get_from_array($acl['name'], "");
			if($aname !== "" && strtolower($name) == strtolower($aname))
				return false;
		}
		
		$ip = file_get_contents("http://whatismyip.akamai.com/");
		$ips = array($ip);
		$postdata = json_encode(array("name"=>$name, "ips"=>$ips));
		$op = "dns/transferAcl/";
		$records = $this->put_data($op, $postdata, 20);
		return $records;
	}
	
	###########################################################################
	
	public function update_acl($name)
	{
		$acls = $this->get_acl_list();
		foreach($acls as $acl) {
			$aname = UTIL::get_from_array($acl['name'], "");
			if($aname !== "" && strtolower($name) == strtolower($aname)) {
				$id = UTIL::get_from_array($acl['id'], "");
				if($id != "") {
					$ip = file_get_contents("http://whatismyip.akamai.com/");
					$ips = array($ip);
					$postdata = json_encode(array("name"=>$name, "ips"=>$ips));
					$op = "dns/transferAcl/{$id}/";
					$records = $this->put_data($op, $postdata, 20);
					return $records;
				}
			}
		}
		return false;
	}
	
	###########################################################################
	
	public static function update_acl_with_current_ip($auth, $aclname="Current ACL", $profile="DNSME")
	{
		$db = $auth->getDatabase();
		$luManager = new \CodePunch\LU\LookupManager($auth);
		$ci = $db->getRegistrarAPIClass($profile, $auth);
		if($ci['class'] != "" && count($ci['params'])) {
			$regapi = new $ci['class']($luManager, ...$ci['params']);
			$whoissupport = $regapi->supported();
			$acl = $regapi->update_acl($aclname);
			UTIL::print($acl);
		}
	}
}

###############################################################################
	
?>