<?php
include(dirname(__FILE__)."/oauth/response.php");
include(dirname(__FILE__)."/oauth/request.php");

class oauth2{
    protected $token_type = 'Bearer';

    private $__request;
    private $__response;
    private $__config;
    private $_token='';

    function __construct($config){
        $this->key = $config['key'];
        $this->secret = $config['secret'];
        $this->site = $config['site'];
        $this->oauth = $config['oauth'];
        $this->__config = $config;
    }

    public function get_token($code)
    {
        $url = "{$this->oauth}/token";
        $data = array(
            'grant_type' => 'authorization_code',
            'code' => $code,
            'redirect_uri' => "",
            'client_id'=>$this->key,
            'client_secret'=>$this->secret,
        );
        $this->request()->get_info($url, $data);
        $params = $this->request()->parsed();
       
        if($params['data']){
            $params= array_merge($params,$params['data']);
        }
        
        $token = $params['access_token'];
        unset($params['expires_in'], $params['token_type'], $params['access_token']);

        $this->token = $token;
        return array('token'=>$token, 'params'=>$params);
    }

    public function authorize_url($callback){
        $data = array(
            'response_type' => 'code',
            'client_id' => $this->key,
            'redirect_uri'=>$callback,
        );
        $query = http_build_query($data);
        $url = "{$this->oauth}/authorize?{$query}";
        return $url;
    }

    public function logout_url($callback)
    {
        $data = array(
            'redirect_uri'=>$callback,
        );
        $query = http_build_query($data);
        $url = "{$this->oauth}/logout?{$query}";
        return $url;

    }

    public function request($token=null)
    {
        if (!$this->__request || $this->_token !== $token){
            $this->_token = $token;
            $this->__request = new oauth2_request($this->__config, $token);
        }
        return $this->__request;
    }

    public function response()
    {
        if (!$this->__response)
            $this->__response = new oauth2_response($this->__config);
        return $this->__response;
    }

    public function verify_api_params()
    {
        $arr_get = $_GET;
        $arr_post = $_POST;
        $sign = $arr_get['sign'];
        $arr_get = $arr_get['sign'];

        #echo "<pre>";
        #print_r($_GET);
        #print_r($_POST);
        return true;
    }

    public function sign($action, $url, $header, $get, $post, $signtime=null)
    {
        $parse_url = parse_url($url);
        $path = $parse_url['path'];
        $get_data['sign_method'] = 'md5';
        $get_data['sign_time'] = $signtime ? $signtime : time();
        $get_data['client_id'] = $this->key;
        //$get_data = array_merge($get, $get_data);
        $get_data = $this->ksort($get_data);
        $post_data = $this->ksort($post);
        $header_data = $this->ksort($header);


        // $get_params = rawurlencode(urldecode(http_build_query($get_data))); 
        $get_params = rawurlencode(urldecode($this->raw_http_build_query($get_data)));
        // $post_params = rawurlencode(urldecode(http_build_query($post_data)));
        $post_params = rawurlencode(urldecode($this->raw_http_build_query($post_data)));
       if ( $header_data)
        {
            // $header_params = rawurlencode(urldecode(http_build_query($header_data)));
            $header_params = rawurlencode(urldecode($this->raw_http_build_query($header_data)));
        }
        else
        {
            $header_params = '';
        }

        #$get_params = $post_params = $header_params = null;
        #foreach(array('get_params' =>$get_data, 'post_params'=>$post_data) as $key => $val){
        #    $$key = $this->build_query($val);
        #}
        #$get_params = rawurlencode(ltrim($get_params, '&'));
        #$post_params = rawurlencode(ltrim($post_params, '&'));
        #$header_params = rawurlencode(ltrim($header_params, '&'));


        $path = rawurlencode('/'.ltrim($path, '/'));

        #$orgsign = "{$this->secret}&".strtoupper($action)."&{$path}&{$get_params}&{$this->secret}";
        $orgsign = "{$this->secret}&".strtoupper($action)."&{$path}&{$header_params}&{$get_params}&{$post_params}&{$this->secret}";
        //echo "<hr>";
        //echo $orgsign,"<HR>";
        
        $sign = strtoupper(md5($orgsign));
        #echo $sign;exit;

        #echo "\r\n", $orgsign, "\r\n", $sign, "\r\n";

        $get_data['sign'] = $sign;
        return $get_data;
    }

    
    private function build_query($row, $pre=null)
    {
        $r = null;
        foreach($row as $k => $v) {
            if(is_array($v)){
                $r .= '&'. $this->build_query($v, ($pre ? "{$pre}[$k]" : $k));
            } else {
                $r .= '&'. ($pre ? "{$pre}[{$k}]" : $k) . "=" .$v;
            }
        }
        return $r;
    }

    private function ksort($data)
    {
        if ( is_array($data))
        {
        ksort($data);
        foreach($data as $key => &$val){
            if (is_array($val)) {
                $val = $this->ksort($val);
            }
        }
        return $data;
        }
        return false;
    }

    function raw_http_build_query($params){
        $arr = array();
        foreach($params AS $key=>$val){
            $arr[] = rawurlencode($key) . "=" . rawurlencode($val);
                }
        return join("&", $arr);
    }




}

