<?php

namespace App\Services\Vendor\BaiduAi;

class ApiBase
{

    /**
     * 获取access token url
     * @var string
     */
    protected $accessTokenUrl = 'https://aip.baidubce.com/oauth/2.0/token';

    /**
     * 反馈接口
     * @var string
     */
    protected $reportUrl = 'https://aip.baidubce.com/rpc/2.0/feedback/v1/report';

    /**
     * appId
     * @var string
     */
    protected $appId = '';

    /**
     * apiKey
     * @var string
     */
    protected $apiKey = '';

    /**
     * secretKey
     * @var string
     */
    protected $secretKey = '';

    /**
     * 权限
     * @var array
     */
    protected $scope = 'brain_all_scope';

    protected $version = "2_2_4";
    protected $isCloudUser = null;
    protected $client;

    public function __construct(string $appId, string $apiKey, string $secretKey)
    {
        $this->appId = $appId;
        $this->apiKey = $apiKey;
        $this->secretKey = $secretKey;
        $this->client = new Request();
    }

    /**
     * 查看版本
     * @return string
     *
     */
    public function getVersion()
    {
        return $this->version;
    }

    /**
     * 反馈
     *
     * @param $feedback
     * @return array
     */
    public function report($feedback)
    {

        $data = array();

        $data['feedback'] = $feedback;

        return $this->request($this->reportUrl, $data);
    }

    /**
     * Api 请求
     * @param  string  $url
     * @param  mixed  $data
     * @param  array  $headers
     * @return mixed
     */
    public function request($url, $data, $headers = array())
    {
        try {
            if (is_array($data)) {
                $data = json_encode($data);
            }

            $result = $this->validate($url, $data);
            if ($result !== true) {
                return $result;
            }

            $params = array();
            $authObj = $this->auth();

            if ($this->isCloudUser === false) {
                $params['access_token'] = $authObj['access_token'];
            }

            // 特殊处理
            $this->proccessRequest($url, $params, $data, $headers);

            $obj = $this->client->post($url, $data, $params, $headers);

            if (!$this->isCloudUser && isset($obj['error_code']) && $obj['error_code'] == 110) {
                $authObj = $this->auth();
                $params['access_token'] = $authObj['access_token'];
                $obj = $this->client->post($url, $data, $params, $headers);
            }
        } catch (\Exception $e) {
            return array(
                'error_code' => 'SDK108',
                'error_msg' => 'connection or read data timeout',
            );
        }

        return $obj;
    }

    /**
     * 格式检查
     * @param  string  $url
     * @param  array  $data
     * @return bool
     */
    protected function validate($url, &$data)
    {
        return true;
    }

    /**
     * 认证
     * @return array
     */
    private function auth()
    {

        $obj = $this->client->get($this->accessTokenUrl, array(
            'grant_type' => 'client_credentials',
            'client_id' => $this->apiKey,
            'client_secret' => $this->secretKey,
        ));

        $this->isCloudUser = !$this->isPermission($obj);

        return $obj;
    }

    /**
     * 判断认证是否有权限
     * @param  array  $authObj
     * @return boolean
     */
    protected function isPermission($authObj)
    {
        if (empty($authObj) || !isset($authObj['scope'])) {
            return false;
        }

        $scopes = explode(' ', $authObj['scope']);

        return in_array($this->scope, $scopes);
    }

    /**
     * 处理请求参数
     * @param  string  $url
     * @param  array  $params
     * @param  array  $data
     * @param  array  $headers
     */
    protected function proccessRequest($url, &$params, &$data, $headers)
    {
        $params['aipSdk'] = 'php';
        $params['aipSdkVersion'] = $this->version;
    }

    /**
     * 通用接口
     * @param  string  $url
     * @param  array  $data
     * @param  array header
     * @return array
     */
    public function post($url, $data, $headers = array())
    {
        return $this->request($url, $data, $headers);
    }

    /**
     * @param  string  $method  HTTP method
     * @param  string  $url
     * @param  array  $params
     * @param  array  $headers
     * @return array
     */
    private function getAuthHeaders($method, $url, $params = array(), $headers = array())
    {

        //不是云的老用户则不用在header中签名 认证
        if ($this->isCloudUser === false) {
            return $headers;
        }
    }
}
