<?php
namespace Meibuyu\Micro\Aspect;

use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Utils\Context;
use Meibuyu\Micro\Annotation\LogTrace;
use Meibuyu\Micro\Handler\LogTrace\LogTraceHandler;
use Psr\Http\Message\ServerRequestInterface;
use Hyperf\Utils\Coroutine;

/**
 * @Aspect(
 *   annotations={
 *      LogTrace::class
 *   }
 * )
 */
class LogTraceAspect extends AbstractAspect
{

    /**
     * 优先级
     * @var int
     */
    public $priority = 999;

    public function process(ProceedingJoinPoint $proceedingJoinPoint)
    {
        try {
            $object  = Context::get(ServerRequestInterface::class);
            $fd = $object?('fd'.$object->getSwooleRequest()->fd):('co'.Coroutine::id());
            Context::set('log_trace_request_id',$fd);

            $originParams = [
                'called_params'=>$proceedingJoinPoint->getArguments(),
                'http_params'=>$object?make(RequestInterface::class)->all():[]
            ];
            LogTraceHandler::createLogTrace(
                $proceedingJoinPoint->className.'@'.$proceedingJoinPoint->methodName,
                $originParams
            );
            $requestId =  LogTraceHandler::getRequestId();
            register_shutdown_function(function ()use($requestId,$originParams,$proceedingJoinPoint) {

               put_log(json_encode([
                   'request_id'=>$requestId,'error_msg'=>error_get_last(),'params'=>$originParams
               ]),
                   str_replace('\\','_',$proceedingJoinPoint->className).
                   '/'.$proceedingJoinPoint->methodName.'/'.date('Ymd').'.txt'
               );
            });
            $result =  $proceedingJoinPoint->process();
            LogTraceHandler::recordProcess('返回结果:'.json_encode($result));
            LogTraceHandler::markComplete();

            return $result;
        }catch (\Throwable $exception){
            LogTraceHandler::recordProcess($exception);
            throw $exception;
        }

    }

}