<?php

defined('SAGEPAY_SDK_PATH') || exit('No direct script access.');

/**
 * The token generated by Sage Pay and provided in response to the registration phase.
 *
 * @category  Payment
 * @package   Sagepay
 * @copyright (c) 2013, Sage Pay Europe Ltd.
 */
class SagepayToken
{

    /**
     * Token constant for transaction type
     */
    const TOKEN = 'TOKEN';

    /**
     * Remove token constant for transaction type
     */
    const REMOVETOKEN = 'REMOVETOKEN';

    /**
     * URL for card registration [RFC1738 valid]
     *
     * @link http://www.ietf.org/rfc/rfc1738.txt
     * @var string
     */
    private $_registerUrl;

    /**
     * URL for card remove [RFC1738 valid]
     *
     * @var string
     */
    private $_removeUrl;

    /**
     * Settings of Sagepay library
     *
     * @var SagepaySettings
     */
    private $_config;

    /**
     * Constructor for Token Helper
     *
     * @param  SagepaySettings  $config  Settings of Sagepay library
     */
    public function __construct(SagepaySettings $config)
    {
        $this->_config = $config;
        $this->_registerUrl = $config->getTokenUrl('register-direct');
        $this->_removeUrl = $config->getTokenUrl('remove');
    }

    /**
     * Get URL for card registration [RFC1738 valid]
     *
     * @return string
     */
    public function getRegisterUrl()
    {
        return $this->_registerUrl;
    }

    /**
     * Set URL for card registration [RFC1738 valid]
     *
     * @uses SagepayValid::url Validate URL field
     * @param string $registerUrl
     */
    public function setRegisterUrl($registerUrl)
    {
        if (SagepayValid::url($registerUrl))
        {
            $this->_registerUrl = $registerUrl;
        }
    }

    /**
     * Get URL for card remove [RFC1738 valid]
     *
     * @return string
     */
    public function getRemoveUrl()
    {
        return $this->_removeUrl;
    }

    /**
     * Set URL for card remove [RFC1738 valid]
     *
     * @uses SagepayValid::url Validate URL field
     * @param string $removeUrl
     */
    public function setRemoveUrl($removeUrl)
    {
        if (SagepayValid::url($removeUrl))
        {
            $this->_removeUrl = $removeUrl;
        }
    }

    /**
     * Prepare data for register request
     * 
     * @param array $cardDetails
     * @return array
     */
    private function _prepareRegisterData(array $cardDetails) 
    {
        return array(
            'VPSProtocol' => $this->_config->getProtocolVersion(),
            'TxType' => self::TOKEN,
            'Vendor' => $this->_config->getVendorName(),
            'Currency' => $this->_config->getCurrency(),
            'CardHolder' => isset($cardDetails['cardHolder']) ? $cardDetails['cardHolder'] : NULL,
            'CardNumber' => isset($cardDetails['cardNumber']) ? $cardDetails['cardNumber'] : NULL,
            'ExpiryDate' => isset($cardDetails['expiryDate']) ? $cardDetails['expiryDate'] : NULL,
            'CV2' => isset($cardDetails['cv2']) ? $cardDetails['cv2'] : NULL,
            'CardType' => isset($cardDetails['cardType']) ? $cardDetails['cardType'] : NULL,
        );
    }
    
    /**
     * Prepare data for remove request
     * 
     * @param string $token
     * @return array
     */
    private function _prepareRemoveData($token) 
    {
        return array(
            'VPSProtocol' => $this->_config->getProtocolVersion(),
            'TxType' => self::REMOVETOKEN,
            'Vendor' => $this->_config->getVendorName(),
            'Token' => $token,
        );
    }

    /**
     * Register card to Sagepay Service
     *
     * @param  string[]  $cardDetails  Associative array with card details
     *
     * @return string|null
     */
    public function register(array $cardDetails)
    {
        $data = $this->_prepareRegisterData($cardDetails);
        $ttl = $this->_config->getRequestTimeout();
        $caCert = $this->_config->getCaCertPath();
        $response = SagepayCommon::requestPost($this->_registerUrl, $data, $ttl, $caCert);
        return isset($response['Token']) ? $response['Token'] : NULL;
    }

    /**
     * Remove token from Sagepay Service
     *
     * @param  string  $token Token GUID provided by Sagepay service on card registration
     *
     * @return boolean
     */
    public function remove($token)
    {
        $data = $this->_prepareRemoveData($token);
        $ttl = $this->_config->getRequestTimeout();
        $caCert = $this->_config->getCaCertPath();
        $response = SagepayCommon::requestPost($this->_removeUrl, $data, $ttl, $caCert);
        return ($response['Status'] == SAGEPAY_REMOTE_STATUS_OK);
    }

}
