<?php
/**
 * 腾讯优图识别-微擎智慧快递版
 * @author 清野软件 晓天
 * https://open.youtu.qq.com
 */
defined('IN_IA') || exit('Access Denied');
class YuTu
{
    const EXPIRED_SECONDS = 2592000;
    const AUTH_URL_FORMAT_ERROR = -1;
    const AUTH_SECRET_ID_KEY_ERROR = -2;
    const PKG_VERSION = '1.0.*';
    const API_YOUTU_END_POINT = 'https://api.youtu.qq.com/';
    const API_YOUTU_CHARGE_END_POINT = 'https://vip-api.youtu.qq.com/';
    public static $_httpInfo = '';//http 请求返回信息
    protected $secretId;
    protected $secretKey;
    protected $appid;
    protected $userid;
    public function __construct(){
        global $_W;
        $wechat = $_W['current_module']['config'];
        $this->appid = $wechat['youtuappid'];
        $this->secretKey = $wechat['youtukey'];
        $this->secretId = $wechat['youtusecret'];
        $this->userid = $wechat['youtuserid'];
    }
    /**
     * 快递单号识别
     * @param  $imgurl 图片地址
     * https://api.youtu.qq.com/youtu/ocrapi/waybillocr
     */
    public function waybillocr($imgurl){
        $expired = time() + self::EXPIRED_SECONDS;
        $postUrl = self::API_YOUTU_END_POINT . 'youtu/ocrapi/waybillocr';
        $sign = $this->appSign($expired);
        $post_data = array(
            'app_id' =>  $this->appid,
            'url' => $imgurl,
        );
        $req = array(
            'url' => $postUrl,
            'method' => 'post',
            'timeout' => 5000,
            'data' => json_encode($post_data),
            'header' => array(
                'Authorization:'.$sign,
                'Content-Type:text/json',
                'Expect: ',
            ),
        );
        $rsp  = $this->send($req);
        $ret  = json_decode($rsp, true);
        if(!$ret){
            return self::getStatusText();
        }

        return $ret;
    }
    /**
     * return the status message
     */
    public static function getStatusText() {
        $info=self::info();
        $status=$info['http_code'];
        var_dump($info);die();
        return self::statusText($status);
    }
    public static function statusText($status)
    {
        switch ($status)
        {
            case 0:
                $statusText = 'CONNECT_FAIL';
                break;
            case 200:
                $statusText = 'HTTP OK';
                break;
            case 400:
                $statusText = 'BAD_REQUEST';
                break;
            case 401:
                $statusText = 'UNAUTHORIZED';
                break;
            case 403:
                $statusText = 'FORBIDDEN';
                break;
            case 404:
                $statusText = 'NOTFOUND';
                break;
            case 411:
                $statusText = 'REQ_NOLENGTH';
                break;
            case 423:
                $statusText = 'SERVER_NOTFOUND';
                break;
            case 424:
                $statusText = 'METHOD_NOTFOUND';
                break;
            case 425:
                $statusText = 'REQUEST_OVERFLOW';
                break;
            case 500:
                $statusText = 'INTERNAL_SERVER_ERROR';
                break;
            case 503:
                $statusText = 'SERVICE_UNAVAILABLE';
                break;
            case 504:
                $statusText = 'GATEWAY_TIME_OUT';
                break;
            default:
                $statusText =$status;
                break;
        }
        return $statusText;
    }
    /**
     * plateocrurl 车牌OCR识别
     * @param $url 待检测的图片url
     * @return 返回的结果，JSON字符串，字段参见API文档
     */
    public  function plateocrurl($url, $seq='') {

        $expired = time() + self::EXPIRED_SECONDS;
        $postUrl = self::API_YOUTU_END_POINT . 'youtu/ocrapi/plateocr';
        $sign = $this->appSign($expired);

        $post_data = array(
            'app_id' =>  $this->appid,
            'url' => $url
        );

        $req = array(
            'url' => $postUrl,
            'method' => 'post',
            'timeout' => 10,
            'data' => json_encode($post_data),
            'header' => array(
                'Authorization:'.$sign,
                'Content-Type:text/json',
                'Expect: ',
            ),
        );

        $rsp  = $this->send($req);
        $ret  = json_decode($rsp, true);

        if(!$ret){
            return self::getStatusText();
        }
        return $ret;
    }
    /**
     * 签名函数
     * @param   $expired    过期时间
     * @param   $userid     暂时不用
     * @return string          签名
     */
    public  function appSign($expired) {
        $secretId = $this->secretId;
        $secretKey = $this->secretKey;
        $appid  =  $this->appid;
        $userid = $this->userid;
        if (empty($secretId) || empty($secretKey)) {
            return self::AUTH_SECRET_ID_KEY_ERROR;
        }

        $now = time();
        $rdm = rand(0,99999);
        $plainText = 'a='.$appid.'&k='.$secretId.'&e='.$expired.'&t='.$now.'&r='.$rdm.'&u='.$userid;
        //var_dump($secretKey);die();
        $bin = hash_hmac("SHA1", $plainText, $secretKey, true);
        $bin = $bin.$plainText;
        $sign = base64_encode($bin);

        return $sign;
    }
    /**
     * send http request
     * @param  array $rq http请求信息
     *                   url        : 请求的url地址
     *                   method     : 请求方法，'get', 'post', 'put', 'delete', 'head'
     *                   data       : 请求数据，如有设置，则method为post
     *                   header     : 需要设置的http头部
     *                   host       : 请求头部host
     *                   timeout    : 请求超时时间
     *                   cert       : ca文件路径
     *                   ssl_version: SSL版本号
     * @return string    http请求响应
     */
    public  function send($rq) {
        $curlHandle = curl_init();
        curl_setopt($curlHandle, CURLOPT_URL, $rq['url']);
        switch (true) {
            case isset($rq['method']) && in_array(strtolower($rq['method']), array('get', 'post', 'put', 'delete', 'head')):
                $method = strtoupper($rq['method']);
                break;
            case isset($rq['data']):
                $method = 'POST';
                break;
            default:
                $method = 'GET';
        }
        $header = isset($rq['header']) ? $rq['header'] : array();
        $header[] = 'Method:'.$method;
        $header[] = 'User-Agent:'.$this->getUA();
        isset($rq['host']) && $header[] = 'Host:'.$rq['host'];
        curl_setopt($curlHandle, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, $method);
        isset($rq['timeout']) && curl_setopt($curlHandle, CURLOPT_TIMEOUT, $rq['timeout']);
        isset($rq['data']) && in_array($method, array('POST', 'PUT')) && curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $rq['data']);
        $ssl = substr($rq['url'], 0, 8) == "https://" ? true : false;
        if( isset($rq['cert'])){
            curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER,true);
            curl_setopt($curlHandle, CURLOPT_CAINFO, $rq['cert']);
            curl_setopt($curlHandle, CURLOPT_SSL_VERIFYHOST,2);
            if (isset($rq['ssl_version'])) {
                curl_setopt($curlHandle, CURLOPT_SSLVERSION, $rq['ssl_version']);
            } else {
                curl_setopt($curlHandle, CURLOPT_SSLVERSION, 4);
            }
        }else if( $ssl ){
            curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER,false);   //true any ca
            curl_setopt($curlHandle, CURLOPT_SSL_VERIFYHOST,2);       //check only host
            curl_setopt($curlHandle, CURLOPT_FOLLOWLOCATION,1);       //check only host
            if (isset($rq['ssl_version'])) {
                curl_setopt($curlHandle, CURLOPT_SSLVERSION, $rq['ssl_version']);
            } else {
                curl_setopt($curlHandle, CURLOPT_SSLVERSION, 4);
            }
        }
        $ret = curl_exec($curlHandle);
        self::$_httpInfo = curl_getinfo($curlHandle);
        curl_close($curlHandle);
        return $ret;
    }
    // 标示SDK 版本
    public  function getUA() {
        return 'YoutuPHP/'.self::PKG_VERSION.' ('.php_uname().')';
    }
    public static function info() {
        return self::$_httpInfo;
    }
}