<?php

/**
 * Yeepay 请求类
 *
 * @author Jeffrey
 * @version $Id: Request.php 91 2010-02-25 15:13:43Z jeffrey $
 */
abstract class Yeepay_Request
{
    /**
     * 签名字段和顺序
     *
     * @var Array
     */
    protected $hashMap = array( # static
        'p0_Cmd' => 'command',
        'p1_MerId' => 'merchantId',
    );

    /**
     * 请求结果对象名称
     *
     * @var string
     */
    protected $responseClass; # static

    /**
     * 业务类型
     *
     * @var string(20)
     */
    protected $command;

    /**
     * 商户编号
     *
     * @var string(11)
     */
    protected $merchantId;

    /**
     * Yeepay 对象
     *
     * @var Yeepay
     */
    protected $yeepay;

    /**
     * 新建 Yeepay 请求对象
     *
     * @param Yeepay $yeepay
     * @return Yeepay_Request
     */
    public function __construct(Yeepay $yeepay)
    {
        $this->yeepay = $yeepay;
        $this->merchantId = $yeepay->getMerchantId();
    }

    /**
     * 使用数组对属性进行赋值
     *
     * @param Array $data
     */
    public function setFromArray(Array $data)
    {
        foreach ($data as $key => $value)
        {
            if (property_exists($this, $key)) {
                $this->$key = $value;
            }
        }
    }

    /**
     * 获取当前请求的 Yeepay 对象
     *
     * @return string
     */
    public function getYeepay()
    {
        return $this->yeepay;
    }

    /**
     * 获取当前请求的业务类型
     *
     * @return string
     */
    public function getCommand()
    {
        return $this->command;
    }

    /**
     * 获取当前请求的商户编号
     *
     * @return string
     */
    public function getMerchantId()
    {
        return $this->merchantId;
    }

    /**
     * 获取当前请求的 HMAC-MD5 信息
     *
     * @return string
     */
    public function getHmac()
    {
        return $this->yeepay->getHmac($this->getHashString());
    }

    /**
     * 获取当前请求的请求地址
     *
     * @return string
     */
    public function getRequestUrl()
    {
        return $this->yeepay->getRequestUrl($this->command);
    }

    /**
     * 获取当前请求结果
     *
     * @return Yeepay_Response
     */
    public function getResponse()
    {
        $data = array();
        $class = get_class($this);

        $requestUrl = $this->getRequestUrl($this->command);
        $requestData = $this->getRequestData();

        $result = $this->request($requestUrl, $requestData);

        if (array() === $result)
        {
            throw new Yeepay_Exception('未知的支付错误');
        }

        return new $this->responseClass($this->getYeepay(), $result);
    }

    /**
     * 获取签名属性字符串
     *
     * @return string
     */
    protected function getHashString()
    {
        $class = get_class($this);
        $result = '';

        $hashMap = $this->hashMap;

        foreach ($hashMap as $key => $property)
        {
            $result .= $this->$property;
        }

        return $result;
    }

    /**
     * 获取请求数据
     *
     * @return Array
     */
    protected function getRequestData()
    {
        $result = array();
        $class = get_class($this);

        $hashMap = $this->hashMap;

        foreach ($hashMap as $key => $property)
        {
            $result[$key] = iconv('UTF-8', 'GBK', $this->$property);
        }

        $result['hmac'] = $this->getHmac();

        return $result;
    }

    /**
     * 进行 HTTP 请求
     * @param mixed $url
     * @param mixed $data
     * @return string
     */
    protected function request($url, $data)
    {
        $array = array();
        $response = HttpClient::quickPost($url, $data);
        $explode = explode("\n", $response);
        foreach ($explode as $value)
        {
            if (!empty($value))
            {
                $tmp = explode('=', $value);
                $array[$tmp[0]] = $tmp[1];
            }
        }

        return $array;
    }
}