<?php namespace sc;

class Request
{
    /**
     * 获取GET请求
     *
     * @param string|array $index
     * @param int          $filter
     *
     * @return mixed
     */
    public function get($index = null, $filter = FILTER_DEFAULT)
    {
        return $this->fetch('get', $index, $filter);
    }

    /**
     * 获取POST请求
     *
     * @param string|array $index
     * @param int          $filter
     *
     * @return mixed
     */
    public function post($index = null, $filter = FILTER_DEFAULT)
    {
        return $this->fetch('post', $index, $filter);
    }

    /**
     * 获取COOKIE
     *
     * @param string|array $index
     * @param int          $filter
     *
     * @return mixed
     */
    public function cookie($index = null, $filter = FILTER_DEFAULT)
    {
        return $this->fetch('cookie', $index, $filter);
    }

    /**
     * 获取SERVER
     *
     * @param string|array $index
     * @param int          $filter
     *
     * @return mixed
     */
    public function server($index = null, $filter = FILTER_DEFAULT)
    {
        return $this->fetch('server', $index, $filter);
    }

    /**
     * 获取客户端IP
     *
     * @return string
     */
    public function ip()
    {
        foreach (['HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP', 'REMOTE_ADDR'] as $index) {
            if (null !== $ip = $this->server($index)) {
                sscanf($ip, '%[^,]', $ip);
                if (!(bool)filter_var($ip, FILTER_VALIDATE_IP)) {
                    $ip = null;
                } else {
                    return $ip;
                }
            }
        }

        return '0.0.0.0';
    }

    /**
     * 获取请求方法
     *
     * @return string
     */
    public function method()
    {
        return strtolower($this->server('REQUEST_METHOD'));
    }

    /**
     * 检查请求是否以Ajax形式发送
     *
     * @return bool
     */
    public function isAjax()
    {
        $ajax = $this->server('HTTP_X_REQUESTED_WITH');

        return !empty($ajax) && 0 === strcasecmp('XMLHttpRequest', $ajax);
    }

    /**
     * 获取user agent
     *
     * @return string
     */
    public function userAgent()
    {
        return $this->server('HTTP_USER_AGENT');
    }

    /**
     * 获取原始输入
     *
     * @param bool $array
     *
     * @return string|array
     */
    public function rawInput($array = true)
    {
        $body = file_get_contents('php://input');

        if ($array) {
            parse_str($body, $output);

            return $output;
        } else {
            return $body;
        }
    }

    /**
     * 取全局数组值
     *
     * @param string       $type
     * @param string|array $index
     * @param int          $filter
     *
     * @return mixed
     */
    private function fetch($type, $index = null, $filter = FILTER_DEFAULT)
    {
        if (null === $index) {
            switch ($type) {
                case 'get':$vars = isset($_GET) ? $_GET : null;break;
                case 'post':$vars = isset($_POST) ? $_POST : null;break;
                case 'cookie':$vars = isset($_COOKIE) ? $_COOKIE : null;break;
                case 'server':$vars = isset($_SERVER) ? $_SERVER : null;break;
                default:return null;break;
            }

            $values = [];
            foreach ($vars as $index => $var) {
                $values[$index] = is_array($var) ? $this->fetch($type, $index, $filter) : filter_var($var, $filter);
            }

            return $values;
        }

        if (is_array($index)) {
            $values = [];
            foreach ($index as $key) {
                $values[$key] = $this->fetch($type, $key, $filter);
            }

            return $values;
        }

        switch ($type) {
            case 'get':return isset($_GET[$index]) ? $_GET[$index] : null;break;
            case 'post':return isset($_POST[$index]) ? $_POST[$index] : null;break;
            case 'cookie':return isset($_COOKIE[$index]) ? $_COOKIE[$index] : null;break;
            case 'server':return isset($_SERVER[$index]) ? $_SERVER[$index] : null;break;
            default:return null;break;
        }
    }
}