<?php
$content = '';
//trace
$backtrace = $error['backtrace'] ?: debug_backtrace();
$traceList = [];
//trace过滤列表
$traceFilter = [
    ['mvc', 'execute'], //[类名,方法名]
    ['mvc', 'errorMake'],
    ['mvc', 'errorReport'],
    'admin/index.php', //文件名
    'lib/sqler.php',
    'lib/pdoHelper.php',
];
$argMaxLen = self::$cfg['BACKTRACE_FULL'] ? 2048 : 100;
foreach ($backtrace as $trace) {
    $dirfile = $trace['file'];
    $trace['file'] = str_replace('\\', '/', $trace['file']);
    if (!self::$cfg['BACKTRACE_FULL']) {
        $trace['file'] = str_replace(\mvc::$cfg['ROOT'], '/', $trace['file']);
        //过滤哪些类和方法
        $isFilter = false;
        foreach ($traceFilter as $filter) {
            if (is_array($filter)) {
                if (isset($filter[1]) && !empty($filter[1])) {
                    if ($trace['class'] == $filter[0] && $trace['function'] == $filter[1]) {
                        $isFilter = true;
                        break;
                    }
                }else{
                    if ($trace['class'] == $filter[0]) {
                        $isFilter = true;
                        break;
                    }
                }
            } else if (strpos($trace['file'], $filter) !== false) {
                $isFilter = true;
                break;
            }
        }
        if ($isFilter) continue;
    }

    if (!$trace['class']) continue;

    if(empty($error['file'])){
        $error['file'] = $dirfile;
        $error['line'] = $trace['line'];
    }

    foreach ($trace['args'] as $k => $v) {
        $type = gettype($v);
        if ($type == 'string') {
            $v = strlen($v) > $argMaxLen ? mb_substr($v, 0, $argMaxLen) . '...' : $v;
            $v = '<span style="color:#a31515">"' . $v . '"</span>';
        } else if ($type == 'array') {
            $json = json_encode($v, JSON_UNESCAPED_UNICODE);
            $json = strlen($json) > $argMaxLen ? mb_substr($json, 0, $argMaxLen) . '...' : $json;
            $v = '<span style="color:#00f">Array</span>(<span style="color:#a31515">' . $json . '</span>)';
        } else if ($type == 'object') {
            $json = json_encode($v, JSON_UNESCAPED_UNICODE);
            $json = strlen($json) > $argMaxLen ? mb_substr($json, 0, $argMaxLen) . '...' : $json;
            $v = '<span style="color:#00f">' . get_class($v) . '</span>(<span style="color:#a31515">' . $json . '</span>)';
        } else {
            $v = '<span style="color:#31938B">' . $v . '</span>';
        }
        $v = ' ' . $v;
        $trace['args'][$k] = $v;
    }
    if (!self::$cfg['BACKTRACE_FULL'] && strpos($trace['file'], 'mvc.php') !== false) {
        $traceList[] = qgprintf('<b>{:class}</b>{:type}<span style="color:#008">{:function}</span>({:args} )', $trace);
    } else {
        $traceList[] = qgprintf('{:file} ({:line}) <b>{:class}</b>{:type}<span style="color:#008">{:function}</span>({:args} )', $trace);
    }
}

$traceMsg = '';
foreach ($traceList as $v) {
    if ($traceMsg != '') $traceMsg .= '<br />';

    $traceMsg .= $v;
}

if(in_array($error['type'],[E_USER_WARNING,E_USER_NOTICE])){
    $content = json_encode(['code'=>ERR_USER_WARNING,'message'=>$error['message']], JSON_UNESCAPED_UNICODE);
}elseif(in_array($error['type'],[2,4,E_ERROR,E_PARSE,E_CORE_ERROR,E_COMPILE_ERROR
                                ,E_USER_ERROR,E_USER_WARNING,E_USER_NOTICE])){
    //code                                        
    $codes = strpos( $error['file'],'eval()')!==false 
                ? explode("<{line}}>",implode("\r\n<{line}}>",explode("\r\n",\mvc::$temp['eval_code_doing']))) 
                : file($error['file']);
    $begin = $error['line'] - 12;
    $end   = $error['line'] + 10;
    $begin = ($begin<0) ? 0 : $begin;
    $end   = ($end>count($codes)) ? count($codes) : $end;
    $code_string  = '<div style="width:100%;height:600px;overflow:auto;background-color:#fff;color:#000000;border: 1px #ddd solid;padding:0;">';
    $code_string .= '<div style="width:2000px;font-size:16px;line-height:24px;border-bottom:1px #ccc dashed;
                    white-space:pre-wrap;padding:0;margin:0">';
    for($i=$begin;$i<=$end;$i++){
        if($i+1==$error['line']) $code_string.= '<div style=";background-color:#FFCCCC;">';
        if(isset($codes[$i])) $code_string.= '<span style="color:#666">'
                    .(
                        ($i+1==$error['line']) ? 
                        '<span style="color:red">'.str_pad((string)($i+1),6,' ',STR_PAD_LEFT).'</span>'
                        :
                        str_pad((string)($i+1),6,' ',STR_PAD_LEFT) 
                    )
                    . "</span>  "
                    //. (($i+1==$error['line']) ? '<strong>':'') 
                    . htmlspecialchars((string)$codes[$i])
                    //. (($i+1==$error['line']) ? '</strong>':'') 
                    ;
        if($i+1==$error['line']) $code_string.= '</div>';
    }
    $code_string = function_exists('phpCodeColor') ? phpCodeColor($code_string) : $code_string;
    $code_string .= '</div></div>';
    $errFileInfo = pathinfo(str_replace('\\','/',$error['file']));
    if (!self::$cfg['BACKTRACE_FULL']) {
        $errFileInfo['dirname'] = str_replace(\mvc::$cfg['ROOT'], '/', $errFileInfo['dirname']);
    }

    //request
    if (\mvc::$req) {
        if (strlen(json_encode(\mvc::$req)) > 1024) {
            $request = substr(json_encode(\mvc::$req), 0, 1024) . '......';
        } else {
            $request = var_export(\mvc::$req, true);
        }
    }
    //msg
    $msg = '';
    $msg .= "<div style='color:#069;font-size:18px;word-break: break-all;'>Action: \\"
    . str_replace('/', '\\', \mvc::$action) . '->' . \mvc::$method . "(" . implode(',', \mvc::$params)
        . ")</div>";
    $msg .= '<div style="font-size:16px;word-break:reak-all;white-space:pre-wrap;">'
    . $errFileInfo['dirname'] . '/<span style="color:red">' . $errFileInfo['basename'] . '</span>'
        . '  Line: <span style="color:red">' . $error['line'] . '</span></div>';
    $msg .= '<div style="font-weight:300;font-size:16px;width:100%;border: 1px #ddd solid;padding: 0.3em;background-color:#FEE;
                white-space:pre-wrap;word-break:break-word;">['
                .$error['type'].'] '. $error['message'].'</div>';
    if($error['sql']){
        $msg .= '<div style="color:#C0C;font-size:16px;word-break: break-all;
                background-color:#FFF">'. \SqlFormatter::format($error['sql']).'</div>';
    }
    if($traceMsg){
        $msg .= '<div style="background-color:#eee;color:#666;border-left: 1px #ddd solid;border-right: 1px #ddd solid;
                padding:10px;color:#000;font-size:14px;overflow:auto;">'. $traceMsg .'</div>';
    }
    $msg .= $code_string;
    $msg .= "<div style='color:#069;font-size:18px;word-break:reak-all;white-space:pre-wrap;'>Request: " . $request . "</div>";

    //content
    $content = '
        <style>pre{font-size:16px;margin:0}</style>
        <div style="clear:both;word-wrap: break-word;
            font-family: monaco, Consolas, Menlo, Courier, monospace;
            font-size: 14px;border: 1px #c66 dashed;border-radius: 5px;
            margin:20px;padding: 20px;background-color:#FFFFE1" class="rare_shutdown_catch_error">';
    $content .=  $msg;
    $content .= '</div>';
}else if($error['type']==E_NOTICE){
    //do nothing
}else{
    $content = dumpResult($error);
}
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR])) {
    tolog($error, 'error');
}

return $content;