<?php

/**
 * composer require phpdocumentor/reflection-docblock
 */

use xmvc\Cache;
use xmvc\Encoder;

$cacheDir = $this->parseDir($type);
$dirs = $this->codeDirArr($type);

$cacheFile = new Cache();
$cacheFile->setCacheFileAbsDir($cacheDir);
$cacheFile->customCacheFileKey = function ($key, Cache $that) {
    $arr = explode('.', $key);
    $key = $arr[0];
    if (I('type') == 'xmvc') {
        if (substr($key, 0, 6) == '[MVC]/') {
            $key = substr($key, 6);
        }
        return 'xmvc_' . str_replace('/', '_', $key);
    } else {
        return str_replace('/', '_', $key);
    }
};

$cacheFile->customCacheFileDir = function ($key, Cache $that) {
    return $that->cacheFileDir;
};

ob_clean();
ob_start();
set_time_limit(3600);
$allFiles = [];
$allMethods = [];
foreach ($dirs as $dir) {
    if ($handle = opendir($dir)) {
        while (false !== ($file = readdir($handle))) {
            if ($file != "." && $file != "..") {
                $path = $dir . "/" . $file;
                // 首字母大写的文件
                if (ctype_upper(substr($file, 0, 1)) && is_file($path)) {
                    $cacheKey = relDir($path);
                    $cacheFileName = $cacheFile->getCacheFileName($cacheKey);
                    if (is_file($cacheFileName) && filemtime($cacheFileName) > filemtime($path)) {
                        $data = require($cacheFileName);
                    } else {
                        $data = $this->parsePhpDoc($path);
                    }
                    $data['filename'] = $path;
                    $data['relFile'] = $cacheKey;
                    $data['parseFile'] = Encoder::encode($cacheFileName);
                    echo $file . "<br>\n";
                    ob_flush();
                    $cacheFile->saveCacheFile($cacheKey, $data);
                    $allFiles[$data['type']][$data['namespace']][] = [
                        'filename' => $data['filename'],
                        'relFile' => $data['relFile'],
                        'summary' => isset($data['docBlock']['summary']) ?  $data['docBlock']['summary'] : '',
                        'type' => $data['type'],
                        'name' => $data['name'],
                        'namespace' => $data['namespace'],
                        'extends' => isset($data['docBlock']['extends']) ?  $data['docBlock']['extends'] : '',
                        'parseFile' => Encoder::encode($cacheFileName),
                    ];
                    $methods = [];
                    if (isset($data['methods'])) {
                        $methods = $data['methods'];
                    } elseif (isset($data['functions'])) {
                        $methods = $data['functions'];
                    }
                    foreach ($methods as $method) {
                        if (!isset($method['visibility']) || $method['visibility'] == 'public') {
                            $summary = '';
                            if (isset($method['docBlock'])) {
                                $summary = explode("\n", $method['docBlock']['summary'])[0]; // 只取第一行描述
                            }
                            $paramString = $this->getParamsString($method['parameters']);
                            $returnTypeStr = $this->getReturnTypeString($method);
                            $methodStr =  $method['name'];
                            if ($data['name'] == 'Function.php') {
                                $methodStr =  'XMVC函数库 ' . $method['name'];
                            } else {
                                $zx = $method['isStatic'] ? '::' : '->';
                                $methodStr =  $data['name'] . $zx . $method['name'];
                            }
                            $methodStr .=  ' (' . $paramString . '): <span class="param-return">' . $returnTypeStr . '</span>';
                            $allMethods[] = [
                                'function' =>  $method['name'],
                                'method' =>  $methodStr,
                                'summary' => $summary,
                                'parseFile' => Encoder::encode($cacheFileName),
                            ];
                        }
                    }
                }
            }
        }
        closedir($handle);
    }
}
$cacheFile->saveCacheFile('allFiles', $allFiles);
$cacheFile->saveCacheFile('allMethods', $allMethods);
ob_end_flush();
