<?php

require_once dirname(__FILE__).'/../../../../lib-tk/shield.php';

require_once ('lib-tk/include/xml/xml.php');
require_once ('lib-mbapi/include/modules/registrar/registrar.php');
require_once ('lib-mbapi/include/curl/curl.php');
require_once ('lib-action/include/input/input.php');
require_once ('lib-mbapi/include/modules/registrar/core/rucenter/RuCenterModule.php');

// Specific Rucenter Exceptions
class RucenterModuleError extends Exception {}

/* Registrar class */

$className = 'RuCenter';
$GLOBALS['moduleInfo'][$className] = array(
    'type'          =>      'registrar',
    'status'        =>      'TRANS_STABLE',
    'version'       =>      '1.0.0',
    'displayName'   =>      'RuCenter',
    'author'        =>      'Parallels',
);


class RuCenter extends Registrar
{
	const RUCENTER_ORG_TYPE = 'ORG';
	const RUCENTER_BUSINESS_PERSON_TYPE = 'PRS';
	const RUCENTER_INDIVIDUAL_TYPE = 'PRS';

	/**
	* The constant to represent a non-finished operation.
	*/
	const ACTION_STATUS_WAITING = "waiting";

	/**
	* The constant to represent a completed operation.
	*/
	const ACTION_STATUS_COMPLETED = "completed";

	/**
	* The constant to represent a errored operation.
	*/
	const ACTION_STATUS_ERROR = "error";

    public function getModuleInfo() {
        return $GLOBALS['moduleInfo']['RuCenter'];
    }

    public function __construct($input) {

	    // quick fix to enable IDN support across all functions
	    if (isset($this->input['domainSLD']) && trim($this->input['domainSLD']) != '') {
	        $this->input['domainSLD'] = $this->getPUNYCode($this->input['domainSLD']);
	    }

		$this->capabilities[REGISTRAR_REGISTERDOMAIN] = 1;
		$this->capabilities[REGISTRAR_TRANSFERDOMAIN] = 0;
		$this->capabilities[REGISTRAR_RENEWDOMAIN] = 0;
		$this->capabilities[REGISTRAR_GETDOMAINEXTENDEDINFO] = 1;
		$this->capabilities[REGISTRAR_CHECKDOMAINAVAILABILITY] = 1;
		$this->capabilities[REGISTRAR_CHECKDOMAINTRANSFERAVAILABILITY] = 0;

		//Domain Management options
		$this->capabilities[REGISTRAR_GETDOMAINCONTACTDATA] = 1;
		$this->capabilities[REGISTRAR_SETDOMAINCONTACTDATA] = 0;
		$this->capabilities[REGISTRAR_GETDOMAINRENEWTYPEOPTIONS] = 0;
		$this->capabilities[REGISTRAR_SETDOMAINRENEWTYPEOPTIONS] = 0;
		$this->capabilities[REGISTRAR_GETDOMAINREGISTRARLOCKOPTIONS] = 0;
		$this->capabilities[REGISTRAR_SETDOMAINREGISTRARLOCKOPTIONS] = 0;
		$this->capabilities[REGISTRAR_GETDOMAINACCESSPASSWORD] = 0;
		$this->capabilities[REGISTRAR_SETDOMAINACCESSPASSWORD] = 0;
		$this->capabilities[REGISTRAR_GETDOMAINDNS] = 1;
		$this->capabilities[REGISTRAR_SETDOMAINDNS] = 1;
		$this->capabilities[REGISTRAR_GETDOMAINRENEWDATE] = 0;
		$this->capabilities[REGISTRAR_LIVERENEW] = 0;

		$this->capabilities[REGISTRAR_CHECKACCOUNTBALANCE] = 0;
		$this->capabilities[REGISTRAR_GETTLDPRICING] = 0;
		$this->capabilities[REGISTRAR_GETTRANSFERSTATUS] = 0;
		$this->capabilities[REGISTRAR_GETTLDLIST] = 0;
		$this->capabilities[REGISTRAR_TLDS] = array_merge($this->contractOnlyTlds, $this->contactRequiredTlds);
		parent::Registrar($input);
		$this->capabilities[REGISTRAR_UPLOADDOCUMENTS] = 1;

     }

    // this function sends the call to register a new domain
    public function registerDomain()
    {
    	// initialize the arrayData variable
        $this->arrayData = array();
        try {

        	if (isset($this->input["domain_orderID"]) && "" != $this->input["domain_orderID"]) {
				$orderInfoRequest = $this->getOrderInfoRequest($this->input);
			    $orderInfoResponse = $this->makeTheCall($orderInfoRequest);
			    require_once("objects/Package.php");
			    switch ($orderInfoResponse->getBody()->getSection('order')->getParameter("state")->getValue()) {
			    	case self::ACTION_STATUS_COMPLETED :
			    		$this->commandStatus = self::ACTION_STATUS_COMPLETED;
			    		$this->arrayData["state"] = $orderResponse->getBody()->getSection("order")->getParameter("state")->getValue();
			    		break;
			    	case self::ACTION_STATUS_WAITING :
			    		$this->commandStatus = self::ACTION_STATUS_WAITING;
			    		$this->arrayData["PackageStatus"] = Package::STATUS_WORKINPROGRESS;
			    		$this->addError(blmsg("TRANS_REGISTRAR_RUCENTER_INPROGRESS"));
			    		break;
			    	default:
			    		$this->arrayData["PackageStatus"] = Package::STATUS_WORKINPROGRESS;
			    		$this->addError(blmsg("TRANS_REGISTRAR_RUCENTER_INPROGRESS"));
			    }
			    $this->setFlagsAndXML(1);
			    return;
        	}

			if (!isset($this->input["domain_subjectContract"])) {
				require_once("lib-tk/include/crypt/crypt.php");
				require_once("object_managers/CryptManager.php");			
				if (!isset($this->input["domain_Password"])) {
					$this->arrayData["Password"] = $this->input["domain_Password"] = CryptManager::encrypt(getRandomPassword(16));
				}
				if (!isset($this->input["domain_TechPassword"])) {
					$this->arrayData["TechPassword"] = $this->input["domain_TechPassword"] = CryptManager::encrypt(getRandomPassword(16));
				}
				$contractRequest = $this->getNewContractRequest($this->input);
			    $contractResponse = $this->makeTheCall($contractRequest);
			    $this->arrayData["subjectContract"] = $this->input["domain_subjectContract"] = $contractResponse->getBody()->getParameter("login")->getValue();
			}

			if (!in_array($this->input['domainTLD'], $this->contractOnlyTlds) && !isset($this->input["domain_nicHdl"])) {
				$contactRequest = $this->getNewContactRequest($this->input);
				$contactResponse = $this->makeTheCall($contactRequest);
				$this->arrayData["nicHdl"] = $this->input["domain_nicHdl"] = $contactResponse->getBody()->getSection('contact')->getParameter("nic-hdl")->getValue();
			}

			$orderRequest = $this->getNewOrderRequest($this->input);
			$orderResponse = $this->makeTheCall($orderRequest);

			$this->arrayData["orderID"] = $orderResponse->getBody()->getSection("order")->getParameter("order_id")->getValue();
			$this->commandStatus = self::ACTION_STATUS_WAITING;
			$this->arrayData["PackageStatus"] = Package::STATUS_WORKINPROGRESS;
			$this->addError(blmsg("TRANS_REGISTRAR_RUCENTER_INPROGRESS"));
			$this->setFlagsAndXML(1);

        } catch (RucenterModuleError $e) {
			$this->addError(blmsg("TRANS_REGISTRARERROR"), $e->getMessage());
			$this->commandStatus = self::ACTION_STATUS_ERROR;
			$this->setFlagsAndXML(0);
        }

    }

    public function getAllDomainContractParams()
    {
    	$nonRequiredParams = array(
    		"domain_subjectContract", "domain_Descr", "domain_ContractType", "domain_Password",
			"domain_OwnerFaxNo", "domain_OwnerMntNfy", "domain_OwnerDestAddr", "domain_TechPassword",
    	);
    	return array_merge(
    		$nonRequiredParams,
    		$this->getRequiredCommonContractParams(),
    		$this->getRequiredOrganizationContractParams(),
    		$this->getRequiredEnterpreneurContractParams()
    	);
    }

    public function getRequiredCommonContractParams()
    {
    	return array(
    		"domain_OwnerEmail", "domain_OwnerCountryID", 
    		"domain_OwnerPhone", "domain_OwnerPostAddr",
    		"domain_OwnerCurrencyID",
    	);
    }

    public function getRequiredIndividualContractParams()
    {
    	$unique = array(
    		"domain_OwnerPerson", "domain_OwnerPersonRus",
    		"domain_OwnerPassport", "domain_OwnerBirthdate",
    	);
    	return array_merge( $this->getRequiredCommonContractParams(), $unique );
    }

    public function getRequiredOrganizationContractParams()
    {
    	$unique = array(
    		"domain_OwnerOrgName", "domain_OwnerOrgRusName",
    		"domain_OwnerCode", "domain_OwnerKpp", "domain_OwnerAddressRus",
    	);
    	return array_merge( $this->getRequiredCommonContractParams(), $unique );
    }

    public function getRequiredEnterpreneurContractParams()
    {
    	return array_merge($this->getRequiredIndividualContractParams(), array('domain_OwnerCode'));
    }


	public function hideContactForm($tld)
	{
		if (!in_array($tld, $this->contractOnlyTlds)) {
			return 0;
		}
		
		return 1;
	}

	public function isDone()
	{
		if (self::ACTION_STATUS_WAITING == $this->commandStatus) {
			return false;
		}

		return true;
	}
	
	public function getTLDParamsData($tld)
	{
		require_once("objects/Client.php");
		$countries = array();
        foreach (Factory()->CountryList() as $country) {
        	$temp["title"] = blmsg("TRANS_ISO_3166_".$country->countries_iso_2);
        	$temp["value"] = $country->countries_iso_2;
        	$countries[] = $temp;
        }
        $currencies = array();
        foreach (Factory()->CurrencyList() as $currency) {
        	$temp["title"] =  $currency->id." - ".blmsg($currency->currency_name);
        	$temp["value"] = $currency->id;
        	$currencies[] = $temp;
        }    
        $nonRequiredParams = array("domain_Descr", "domain_OwnerFaxNo", "domain_OwnerMntNfy", "domain_ContractType"); 
		return array(
			"title" => "TRANS_REGISTRAR_RUCENTER_CONTRACT_DATA",
			"additionalMessage" => "TRANS_REGISTRAR_RUCENTER_REGISTRATION_ADDITIONAL_INFO",
			"attributes" => array(
				array(
					"name" => "domain_ContractType",
					"description" => "TRANS_REGISTRAR_RUCENTER_CLIENT_TYPE",
					"validationRequiredParams" => true,
					"allDomainParams" => $this->getAllDomainContractParams(),
					"defaultValue" => Client::TYPE_INDIVIDUAL_PERSON,
					"options" => array(
						array(
							"title" => "TRANS_REGISTRAR_RUCENTER_INDIVIDUAL_PERSON",
							"value" => Client::TYPE_INDIVIDUAL_PERSON,
							"paramsToShow" => array_merge($this->getRequiredIndividualContractParams(),$nonRequiredParams),
						),
						array(
							"title" => "TRANS_REGISTRAR_RUCENTER_COMMERCIAL_COMPANY",
							"value" => Client::TYPE_COMMERCIAL_COMPANY,
							"paramsToShow" => array_merge($this->getRequiredOrganizationContractParams(),$nonRequiredParams, array('domain_OwnerDestAddr')),
						),
						array(
							"title" => "TRANS_REGISTRAR_RUCENTER_INDIVIDUAL_ENTERPRENEUR",
							"value" => Client::TYPE_INDIVIDUAL_ENTERPRENEUR,
							"paramsToShow" => array_merge($this->getRequiredEnterpreneurContractParams(),$nonRequiredParams),
						),
					),					
				),
				array(
					"name" => "domain_OwnerPerson",
					"description" => "TRANS_REGISTRAR_RUCENTER_CLIENT_ENG",	
					"userdefined" => "True",
				),
				array(
					"name" => "domain_OwnerPersonRus",
					"description" => "TRANS_REGISTRAR_RUCENTER_CLIENT_RUS",	
					"userdefined" => "True",
				),
				array(
					"name" => "domain_OwnerPassport",
					"description" => "TRANS_REGISTRAR_RUCENTER_PASSPORT",	
					"hint" => "TRANS_REGISTRAR_RUCENTER_PASSPORT_HINT",
					"userdefined" => "True",
					"multiline" => "True",
				),
				array(
					"name" => "domain_OwnerBirthdate",
					"userdefined" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_CLIENT_BIRTHDAY",
				),
				array(
					"name" => "domain_OwnerOrgName",
					"userdefined" => "True",
					"multiline" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_COMMERCIAL_COMPANY_NAME",
				),
				array(
					"name" => "domain_OwnerOrgRusName",
					"userdefined" => "True",
					"multiline" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_COMMERCIAL_COMPANY_RUSSIAN_NAME",
					"hint" => "TRANS_REGISTRAR_RUCENTER_COMMERCIAL_COMPANY_RUSSIAN_NAME_HINT",
				),
				array(
					"name" => "domain_OwnerCode",
					"userdefined" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_INN",
					"hint" => "TRANS_REGISTRAR_RUCENTER_INN_HINT",
				),
				array(
					"name" => "domain_OwnerKpp",
					"userdefined" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_KPP",
					"hint" => "TRANS_REGISTRAR_RUCENTER_KPP_HINT",
				),
				array(
					"name" => "domain_OwnerCountryID",
					"description" => "TRANS_REGISTRAR_RUCENTER_COUNTRY",
					"defaultValue" => "RU",
					"options" => $countries,
				),
				array(
					"name" => "domain_OwnerCurrencyID",
					"description" => "TRANS_REGISTRAR_RUCENTER_CURRENCY",
					"hint" => "TRANS_REGISTRAR_RUCENTER_CURRENCY_HINT",
					"defaultValue" => "RUB",
					"options" => $currencies,
				),
				array(
					"name" => "domain_OwnerAddressRus",
					"userdefined" => "True",
					"multiline" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_RUSSIAN_ADDRESS",
					"hint" => "TRANS_REGISTRAR_RUCENTER_RUSSIAN_ADDRESS_HINT",
				),
				array(
					"name" => "domain_OwnerPostAddr",
					"userdefined" => "True",
					"multiline" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_POST_RUSSIAN_ADDRESS",
					"hint" => "TRANS_REGISTRAR_RUCENTER_POST_RUSSIAN_ADDRESS_HINT",
				),
				array(
					"name" => "domain_OwnerDestAddr",
					"userdefined" => "True",
					"multiline" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_CONSIGNEE_RUSSIAN_ADDRESS",
					"hint" => "TRANS_REGISTRAR_RUCENTER_CONSIGNEE_RUSSIAN_ADDRESS_HINT",
				),
				array(
					"name" => "domain_OwnerPhone",
					"userdefined" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_PHONE",
					"hint" => "TRANS_REGISTRAR_RUCENTER_PHONE_HINT",
				),
				array(
					"name" => "domain_OwnerFaxNo",
					"userdefined" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_FAX",
					"hint" => "TRANS_REGISTRAR_RUCENTER_FAX_HINT",
				),
				array(
					"name" => "domain_OwnerEmail",
					"userdefined" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_EMAIL",
				),
				array(
					"name" => "domain_OwnerMntNfy",
					"userdefined" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_MNT_NFY",
					"hint" => "TRANS_REGISTRAR_RUCENTER_MNT_NFY_HINT",
				),
				array(
					"name" => "domain_Descr",
					"userdefined" => "True",
					"multiline" => "True",
					"description" => "TRANS_REGISTRAR_RUCENTER_DOMAIN_DESCR",
				),
			),
		);
	}
	
	public function getDomainDNS(PackageDomain $domain) {
		$crypt = new Crypt(getPasswordHash(Crypt::ENCRYPTION_KEY));
		$action = new RuCenterEditDNSAction();
		$action->_mode = RuCenterEditDNSAction::MODE_DISPLAY;
		$action->_login = $this->getParameter("moduleUsername");
		$action->_password = $crypt->decrypt($this->getParameter("modulePassword"));
		$action->_subjectContract = $domain->getPackage()->getAttribute("domain_subjectContract");
		$action->_domain = $domain->domain_sld . "." . $domain->domain_tld;
		$action->_tld = $domain->domain_tld;
		RuCenterModule::setLang(BillingLocale::getLocale());
		$action->run();
		if (!is_null($action->errors)) {
			throw new ProductException(ProductException::E_FAIL_OPERATION, implode("\n", $action->errors));
		}
		return $action->getProperty("nameServers");
	}
	
	public function setDomainDNS(PackageDomain $domain) {
		$crypt = new Crypt(getPasswordHash(Crypt::ENCRYPTION_KEY));
		$action = new RuCenterEditDNSAction();
		$action->_mode = RuCenterEditDNSAction::MODE_PROCESS;
		$action->_login = $this->getParameter("moduleUsername");
		$action->_password = $crypt->decrypt($this->getParameter("modulePassword"));
		$action->_subjectContract = $domain->getPackage()->getAttribute("domain_subjectContract");
		$action->_domain = $domain->domain_sld . "." . $domain->domain_tld;
		$action->_tld = $domain->domain_tld;
		$action->nameServers = isset($_REQUEST["domainDNS"]) ? $_REQUEST["domainDNS"] : array();
		RuCenterModule::setLang(BillingLocale::getLocale());
		$action->run();
		if (!is_null($action->errors)) {
			throw new ProductException(ProductException::E_FAIL_OPERATION, implode("\n", $action->errors));
		}
		return;
	}
	
	public function uploadIdentityDocument(PackageDomain $domain, $identityDocumentFiledName) {
		$crypt = new Crypt(getPasswordHash(Crypt::ENCRYPTION_KEY));
		$action = new RuCenterUploadIdentityDocumentAction();
		$action->_login = $this->getParameter("moduleUsername");
		$action->_password = $crypt->decrypt($this->getParameter("modulePassword"));
		$action->_subjectContract = $domain->getPackage()->getAttribute("domain_subjectContract");
		$action->_domain = $domain->domain_sld . "." . $domain->domain_tld;
		$action->_identity_document_field_name = $identityDocumentFiledName;
		$action->run();
		if (!is_null($action->errors)) {
			throw new ProductException(ProductException::E_FAIL_OPERATION, implode("\n", $action->errors));
		}
		return;
	}

	public function registrarFormatPhone() {}
	
	protected function getDefaultConfigOptions()
	{
    	return array(
    		"TRANS_REGISTRAR_MODULE_SETTINGS" => array(
    			array("moduleEnabled", "b", false, "TRANS_REGISTRAR_RUCENTER_ENABLE", NULL, NULL),
    			array('moduleUsername', "t", NULL, "TRANS_REGISTRAR_RUCENTER_USERNAME", NULL, NULL),
    			array('modulePassword', "p", NULL, "TRANS_REGISTRAR_RUCENTER_PASSWORD", NULL, NULL),
    			array('moduleTestMode', "b", true, "TRANS_REGISTRAR_RUCENTER_ENABLE_TEST_MODE", NULL, NULL),
    			array('moduleUseCustomNameserver', "b", false, "TRANS_REGISTRAR_RUCENTER_USE_CUSTOM_NAMESERVER", NULL, NULL),
    			array('moduleAllowChangeDNS', "b", false, "TRANS_REGISTRAR_RUCENTER_ALLOW_CHANGE_DNS", NULL, NULL),
    			array('moduleAllowUploadDocuments', "b", false, "TRANS_REGISTRAR_RUCENTER_ALLOW_UPLOAD_DOCUMENTS", NULL, NULL)
    		),
    		"TRANS_REGISTRAR_NS" => array(
    			array("domainNameserver1", "t", NULL, "TRANS_REGISTRAR_NS1", NULL, NULL),
				array("domainNameserver2", "t", NULL, "TRANS_REGISTRAR_NS2", NULL, NULL),
				array("domainNameserver3", "t", NULL, "TRANS_REGISTRAR_NS3", NULL, NULL),
				array("domainNameserver4", "t", NULL, "TRANS_REGISTRAR_NS4", NULL, NULL),
    		)
    	);
    }

    private function getRequestID()
    {
    	return date("YmdHis").mt_rand();
    }

    private function getHeader($request, $operation, $input)
    {
    	$header = new RuCenterMessageHeader();
    	$header->login = $this->UID;
    	$header->password = $this->PW;
    	$header->lang = 'en';
    	$header->request = $request;
    	$header->operation = $operation;
    	$header->request_id = $this->getRequestID();

    	$requestWithoutLogin = array(
    		array("contract", "create"),
    		array("order", "get"),
    	);

		if (!in_array( array($request, $operation), $requestWithoutLogin ) ) {
			$header->subject_contract = $input["domain_subjectContract"];
		}
		return $header;
    }

    private function getNewContractRequest(array $input)
    {
    	$header = $this->getHeader("contract", "create", $input);
		$body = new RuCenterMessageBody();
		$section = $body->addSection(new RuCenterMessageSection("contract"));
		require_once("object_managers/CryptManager.php");
		$section->password = CryptManager::decrypt($input['domain_Password']);
		$section->tech_password =  CryptManager::decrypt($input['domain_TechPassword']);
		$addressPost = $this->getMultilineParameter($input['domain_OwnerPostAddr'], 'p-addr');

        $section->addParameter($addressPost);
		$section->phone = $input['domain_OwnerPhone'];
		$section->currency_id = str_replace("RUB", "RUR", $input['domain_OwnerCurrencyID']);
		$section->country = $input['domain_OwnerCountryID'];
		$section->fax_no = $input['domain_OwnerFaxNo'];
		$section->e_mail = $input['domain_OwnerEmail'];
		$section->mnt_nfy = $input['domain_OwnerMntNfy'];

		require_once("objects/Client.php");
		switch ($input['domain_ContractType']) {
			case Client::TYPE_INDIVIDUAL_PERSON :
				$section->contract_type = self::RUCENTER_INDIVIDUAL_TYPE;
				$this->getIndividualTypeContractData($section, $input);
				break;
			case Client::TYPE_INDIVIDUAL_ENTERPRENEUR :
				$section->contract_type = self::RUCENTER_BUSINESS_PERSON_TYPE;
				$this->getBusinessPersonTypeContractData($section, $input);
				break;
			case Client::TYPE_COMMERCIAL_COMPANY :
				$section->contract_type = self::RUCENTER_ORG_TYPE;
				$this->getOrgTypeContractData($section, $input);
				break;
		}

		return new RuCenterRequest($header,$body);
    }

    private function getIndividualTypeContractData(RuCenterMessageSection $section, array $input)
    {
		$section->person = $input['domain_OwnerPerson'];
        $passport = $this->getMultilineParameter($input['domain_OwnerPassport'], 'passport');
        $section->addParameter($passport);
		$section->person_r = $input['domain_OwnerPersonRus'];
		$section->birth_date = $input['domain_OwnerBirthdate'];
    }

    private function getBusinessPersonTypeContractData(RuCenterMessageSection $section, array $input)
    {
    	$section->person = $input['domain_OwnerPerson'];
		$section->person_r = $input['domain_OwnerPersonRus'];
		$passport = $this->getMultilineParameter($input['domain_OwnerPassport'], 'passport');
        $section->addParameter($passport);
		$section->birth_date = $input['domain_OwnerBirthdate'];
		$section->code = $input['domain_OwnerCode'];
		$addressDest = $this->getMultilineParameter($input['domain_OwnerDestAddr'], 'd-addr');
        $section->addParameter($addressDest);
    }

    private function getOrgTypeContractData(RuCenterMessageSection $section, array $input)
    {
    	$orgName = $this->getMultilineParameter($input['domain_OwnerOrgName'], 'org');
        $section->addParameter($orgName);
        $orgRusName = $this->getMultilineParameter($input['domain_OwnerOrgRusName'], 'org-r');
        $section->addParameter($orgRusName);
		$section->code = $input['domain_OwnerCode'];
		$section->kpp = $input['domain_OwnerKpp'];
        $addressRus = $this->getMultilineParameter($input['domain_OwnerAddressRus'], 'address-r');
        $section->addParameter($addressRus);
        $addressDest = $this->getMultilineParameter($input['domain_OwnerDestAddr'], 'd-addr');
        $section->addParameter($addressDest);
    }
    
    private function getMultilineParameter($inputParameterValue, $requestParameterName)
    {
    	$inputParameter = explode(RuCenterMessage::LF, str_replace(RuCenterMessage::CRLF, RuCenterMessage::LF, $inputParameterValue));
		$parameter = new RuCenterMessageParameter($requestParameterName);
        foreach ($inputParameter as $str) {
			$parameter->addValue($str);
        }
        return $parameter;
    }

    private function getNewOrderRequest(array $input)
    {
		$header = $this->getHeader("order", "create", $input);
		$body = new RuCenterMessageBody();
		$section = $body->addSection(new RuCenterMessageSection("order-item"));
		$section->action = 'new';
		$section->descr = $input['domain_Descr'];
        if ( $this->config['moduleUseCustomNameserver'] ) {
            $configNameservers = array(
                'domainNameserver1',
                'domainNameserver2',
                'domainNameserver3',
                'domainnameserver4'
            );
            $nServer = new RuCenterMessageParameter("nserver");
            foreach ($configNameservers as $nameServer) {
				$nServer->addValue($this->config[$nameServer]);
            }
            $section->addParameter($nServer);
        }
		$section->nserver = $input['domain_Nserver'];
		$domain = "{$input['domainSLD']}.{$input['domainTLD']}";

		if (!in_array($input['domainTLD'], $this->contractOnlyTlds)) {
        	$section->template = 'client_rrp';
			$section->period = $input['domainYears'];
			$section->domain = $domain;
			$section->admin_c = $section->bill_c = $section->tech_c = $input['domain_nicHdl'];
		}

		switch ($input['domainTLD']) {
			case "ru":
				$section->service = 'domain_ru';
				$section->template = 'client_ru';
				$section->domain = $domain;
				break;
			case "su":
				$section->service = 'domain_su';
				$section->template = 'client_ru';
				$section->domain = $domain;
				break;
			case "рф":
				$section->service = 'domain_rf';
				$section->template = 'domain_rf';
				$section->domain = billing_idn2ascii("{$input['domainSLD']}.{$input['domainTLD']}");
				break;
			case "me":
				$section->service = 'domain_epp_me';
				break;
			case "lc":
				$section->service = 'domain_epp_lc';
				break;
			case "sc":
				$section->service = 'domain_epp_sc';
				break;
			case "vc":
				$section->service = 'domain_epp_vc';
				break;
			case "cc":
				$section->service = 'domain_epp_cc';
				break;
			case "tv":
				$section->service = 'domain_epp_tv';
				break;
			case "tel":
				$section->service = 'domain_epp_tel';
				break;
			case "mobi":
				$section->service = 'domain_epp_mobi';
				break;
			case "name":
				$section->service = 'domain_epp_name';
				break;
			case "travel":
				$section->service = 'domain_epp_travel';
				$section->uin = $input['domain_nicHdl'];
				break;
			case "aero":
				$section->service = 'domain_epp_aero';
				$section->authid = $section->authkey = $input['domain_nicHdl'];
				break;
			case "pro":
				$section->service = 'domain_epp_pro';
				break;
			case "ag":
				$section->service = 'domain_epp_ag';
				break;
			case "bz":
				$section->service = 'domain_epp_bz';
				break;
			case "hn":
				$section->service = 'domain_epp_hn';
				break;
			case "mn":
				$section->service = 'domain_epp_mn';
				break;
			default:
				$section->service = 'domain_rrp';
				break;
		}
		return new RuCenterRequest($header,$body);
    }


    private function getNewContactRequest(array $input)
    {
		$header = $this->getHeader("contact", "create", $input);
		$body = new RuCenterMessageBody();
		$section = $body->addSection(new RuCenterMessageSection("contact"));
		
		$section->status = (1 == $input['domain_HasContract']) ? 'contact' : 'registrant';
		$section->org = $input['registrantOrganizationName'];
		require_once("objects/Client.php");
		switch ($input['domainContractType']) {
			case Client::TYPE_INDIVIDUAL_PERSON :
			case Client::TYPE_INDIVIDUAL_ENTERPRENEUR :
				$section->name = "{$input['registrantLastName']} {$input['registrantFirstName']}";
				break;
			case Client::TYPE_COMMERCIAL_COMPANY :
				$section->name = $input['registrantOrganizationName'];
				break;
		}
		$section->country = $input['registrantCountry'];
		$section->region = $input['registrantState'];
		$section->city = $input['registrantCity'];
		$section->street = $input['registrantAddress1'];
		$section->zipcode = $input['registrantPostalCode'];
		$section->phone = $input['registrantPhone'];
		$section->fax = $input['registrantFax'];
		$section->email = $input['registrantEmail'];

		return new RuCenterRequest($header,$body);
    }

    private function getOrderInfoRequest(array $input)
    {
		$header = $this->getHeader("order", "get", $input);
		$body = new RuCenterMessageBody();
		$section = $body->addSection(new RuCenterMessageSection("order"));
		$orderID = new RuCenterMessageParameter("order_id");
		$orderID->addValue($input["domain_orderID"]);
		$section->addParameter($orderID);
		return new RuCenterRequest($header,$body);
    }

    // from any function that needs to make a cURL call, we will pass the
    // post values to this function, which will actually make the call
    private function makeTheCall(RuCenterRequest $request)
    {
		try {
			$data = $request->generate();
			if ("" == $data) {
				throw new Exception('Empty request to Rucenter.');
			}
			dbg("Request to Rucenter");
			dbg($data);

			$curl = curl_init();
			$data = mb_convert_encoding($data, "koi8-r", "utf8");
			curl_setopt($curl, CURLOPT_URL, $this->getURL());
			curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($curl, CURLOPT_POST, true);
			curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
			curl_setopt($curl, CURLOPT_POSTFIELDS, array('SimpleRequest' => $data));
			
			$attemptsCount = 0;
			while (!($output = curl_exec($curl)) && $attemptsCount < RuCenterModule::REQUEST_ATTEMPTS_COUNT) {
				$attemptsCount++;
			}
			
			$output = mb_convert_encoding($output, "utf8", "koi8-r");
			
			dbg("Responce from Rucenter");
			dbg($output);
			dbg("CURL error if is:");
			dbg(curl_error($curl));

			$responce = RuCenterResponce::load($output);
			curl_close($curl);

			switch ($responce->getState()) {
				case 200:
					if ($request->getHeader()->getParameter("request-id")->getValue() != $responce->getHeader()->getParameter("request-id")->getValue()) {
						throw new RucenterModuleError("Invalid request-id in Rucenter responce.");
					}
					break;
				default:
					throw new RucenterModuleError(implode("\n", $responce->getErrors()));
					break;
			}

		} catch (Exception $e) {
			throw new RucenterModuleError($e->getMessage());
		}

		return $responce;
    }

    // this function sets the API URL based on whether we're in LIVE mode or TEST mode
    private function getURL()
    {
        return 'https://www.nic.ru/dns/dealer';
    }

    private function setFlagsAndXML($hasExecutedSuccessfully = 0)
    {
	    $this->hasExecutedSuccessfully = $hasExecutedSuccessfully;
        $this->hasExecuted = 1;
        $this->xmlData = $this->getRegistrarReturnXML();
    }

    private $contractOnlyTlds = array('рф', 'ru', 'su');
    private $contactRequiredTlds = array('com', 'net', 'org', 'biz', 'info', 'me', 'lc', 'sc', 'vc',
    	'cc', 'tv', 'tel', 'mobi', 'name', 'travel', 'aero', 'pro', 'ag', 'bz', 'hn', 'mn');
    private $commandStatus;
    private $header;
    private $contract;
    private $orderItem;
}
