<?php
namespace JinDouYun\Controller\Cron;

use JinDouYun\Controller\Common\Logger;
use Mall\Framework\Factory;
use Mall\Framework\Cache\Redis;

/**
 * Description: redis延时队列，订单延时取消
 * Class DelayQueueOrder
 * @package JinDouYun\Controller\Cron
 */
class DelayQueueOrder
{

    /**
     * @var Redis
     */
    private $cache;

    /**
     * @var string
     */
    private $delayQueueCancelOrderKey = 'delay_queue_cancel_order';

    /**
     * @var int
     */
    private $enterpriseId;

    /**
     * DelayQueueOrder constructor.
     * @throws \Exception
     */
    public function __construct()
    {
        $this->cache = Factory::cache('default');
        $params = self::cliParams();
        if (empty($params)){
            Logger::logs(E_USER_ERROR,'命令行参数为空',__CLASS__,__LINE__,$params,true);
            exit();
        }
        $enterpriseId = isset($params['enterpriseId']) ? $params['enterpriseId'] : null;
        if (empty($enterpriseId)){
            Logger::logs(E_USER_ERROR,'enterpriseId参数错误',__CLASS__,__LINE__,true);
            exit();
        }
        $this->enterpriseId = $enterpriseId;
    }

    /**
     * Doc: (des="延时队列，取消订单")
     * User: XMing
     * Date: 2020/9/23
     * Time: 2:36 下午
     */
    public function run()
    {
        while (true){
            //从有序集合中拿到n秒以前的订单
            //TODO 这里要解决每个企业配置不同的订单失效时间问题 (通过命令行传餐 每个企业运行独立的延迟队列)
            //TODO 不能放在初始化中查询企业配置，企业配置是动态的（5分钟查询一次当前企业最新配置）
            $orderIds = $this->cache->zrangebyscore($this->delayQueueCancelOrderKey.'::'.$this->enterpriseId, 0, time()-60, ['withscores' => TRUE]);
            if(empty($orderIds)){
                sleep(1);
                continue;
            }
            //拿出的数据立马删除
            foreach ($orderIds as $orderId => $taskTime) {
                $delRes = $this->cache->zrem($this->delayQueueCancelOrderKey.'::'.$this->enterpriseId, $orderId);
                if (!$delRes){
                    continue;
                }
                Logger::logs(E_USER_ERROR,'消费订单',__CLASS__,__LINE__,$orderId,true);
            }
        }
    }

    /**
     * Doc: (des="获取命令行下传递进来的参数")
     * User: XMing
     * Date: 2020/9/23
     * Time: 4:09 下午
     * @example php test.php -p3 -t=abc --opt=valopt --opt2 valopt2
     * @return array
     */
    private function cliParams()
    {
        $result = array();
        $params = $GLOBALS['argv'];

        array_shift($params);
        do {
            $tmpEachResult = array_shift($params);
            if (!$tmpEachResult) {
                break;
            }
            $p = $tmpEachResult;
            if ($p{0} == '-') {
                $pname = substr($p, 1);
                $value = false;
                if ($pname{0} == '-') {// 长选项 (--<param>)
                    $pname = substr($pname, 1);
                    if (strpos($p, '=') !== false) {
                        // value specified inline (--<param>=<value>)
                        list($pname, $value) = explode('=', substr($p, 2), 2);
                    }
                } else {// 短选项
                    if (strpos($p, '=') !== false) {
                        // value specified inline (-<param>=<value>)
                        list($pname, $value) = explode('=', substr($p, 1), 2);
                    } else if (strlen($p) > 1) {
                        $pname = substr($p, 1, 1);
                        $value = substr($p, 2);
                    }
                }
                # 如果上面没有取到值，并且下一个不是以-开头的，则下一个值为当前参数的值
                $nextparm = current($params);
                if ($value === false
                    && $nextparm !== false
                    && $nextparm{0} != '-'
                ) {
                    $value = array_shift($params);
                }
                $result[$pname] = (string)$value;// 将 false转为空串，以便与http访问时对参数的处理一致
            } else {
                # 不是以-指定开始的参数，一律丢弃
                //$result[] = $p;
            }
        } while (true);
        return $result;
    }
}