<?php
if (!defined('ABSPATH')) {
    exit;
}

function wpfortai_core_check_endpoint($request) {
    global $wp_version;
    $response = array(
        'timestamp' => current_time('mysql'),
        'status' => 'success'
    );

    try {
        // Check WordPress Version
        $core_updates = get_core_updates();
        $response['wordpress'] = array(
            'current_version' => $wp_version,
            'latest_version' => isset($core_updates[0]->version) ? $core_updates[0]->version : $wp_version,
            'update_required' => isset($core_updates[0]->response) && $core_updates[0]->response === 'upgrade',
        );

        // Check PHP Version
        $php_version = phpversion();
        $minimum_recommended = '8.0';
        $response['php'] = array(
            'current_version' => $php_version,
            'minimum_recommended' => $minimum_recommended,
            'upgrade_recommended' => version_compare($php_version, $minimum_recommended, '<'),
        );

        // Core Files Check (now includes PHP file permissions)
        $response['core_files'] = wpfortai_check_core_files();

        // Check write permissions on sensitive directories
        $response['permissions'] = wpfortai_check_directory_permissions();

    } catch (Exception $e) {
        $response['status'] = 'error';
        $response['error'] = $e->getMessage();
        return new WP_REST_Response($response, 500);
    }

    return new WP_REST_Response($response, 200);
}

function wpfortai_check_directory_permissions() {
    $wp_root = ABSPATH;
    $critical_dirs = array(
        'wp-admin' => '0755',
        'wp-includes' => '0755',
        'wp-content' => '0755',
        'wp-content/plugins' => '0755',
        'wp-content/themes' => '0755',
        'wp-content/uploads' => '0755'
    );
    
    // Additional core PHP files to check permissions for
    $core_php_files = array(
        'wp-admin/admin.php' => '0644',
        'wp-admin/admin-ajax.php' => '0644',
        'wp-admin/admin-post.php' => '0644',
        'wp-admin/async-upload.php' => '0644',
        'wp-admin/comment.php' => '0644',
        'wp-admin/edit.php' => '0644',
        'wp-admin/includes/admin.php' => '0644',
        'wp-admin/includes/ajax-actions.php' => '0644',
        'wp-admin/includes/class-wp-posts-list-table.php' => '0644',
        'wp-admin/includes/update.php' => '0644',
        'wp-admin/includes/upgrade.php' => '0644',
        'wp-admin/post.php' => '0644',
        'wp-admin/update.php' => '0644',
        'wp-login.php' => '0644',
        'wp-includes/version.php' => '0644',
        'wp-includes/functions.php' => '0644',
        'wp-includes/pluggable.php' => '0644',
        'wp-includes/capabilities.php' => '0644',
        'wp-includes/class-wp-roles.php' => '0644',
        'wp-includes/class-wp-query.php' => '0644',
        'wp-includes/class-wp-post.php' => '0644',
        'wp-includes/class-wp-hook.php' => '0644',
        'wp-includes/plugin.php' => '0644',
        'wp-includes/user.php' => '0644',
        'wp-includes/general-template.php' => '0644',
        'wp-includes/rewrite.php' => '0644',
        'wp-includes/rest-api.php' => '0644',
        'wp-includes/theme.php' => '0644',
        'wp-includes/update.php' => '0644'
    );

    // Determine server type to handle .htaccess appropriately
    $server_type = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '';
    $is_apache = stripos($server_type, 'apache') !== false;
    $is_nginx = stripos($server_type, 'nginx') !== false;
    $is_litespeed = stripos($server_type, 'litespeed') !== false;
    $is_iis = stripos($server_type, 'microsoft-iis') !== false || stripos($server_type, 'iis') !== false;
    
    // For Apache and LiteSpeed, .htaccess is important
    // For Nginx, IIS, and others, it's not used
    $critical_files = array(
        'wp-config.php' => '0440',
        'index.php' => '0644'
    );
    
    // Only add .htaccess as a critical file for Apache-based servers
    if ($is_apache || $is_litespeed) {
        $critical_files['.htaccess'] = '0644';
    }

    $permissions_check = array(
        'directories' => array(),
        'files' => array(),
        'summary' => array(
            'total_issues' => 0,
            'critical_issues' => 0,
            'warnings' => 0
        ),
        'server_info' => array(
            'type' => $server_type,
            'is_apache' => $is_apache,
            'is_nginx' => $is_nginx,
            'is_litespeed' => $is_litespeed,
            'is_iis' => $is_iis
        )
    );

    // Check directory permissions
    foreach ($critical_dirs as $dir => $recommended_perms) {
        $dir_path = $wp_root . $dir;
        if (is_dir($dir_path)) {
            $perms = substr(sprintf('%o', fileperms($dir_path)), -4);
            $is_writable = wp_is_writable($dir_path);
            $is_readable = is_readable($dir_path);
            
            $status = $perms === $recommended_perms ? 'optimal' : 'warning';
            if ($perms > $recommended_perms) {
                $status = 'critical';
                $permissions_check['summary']['critical_issues']++;
            } elseif ($status === 'warning') {
                $permissions_check['summary']['warnings']++;
            }

            $permissions_check['directories'][$dir] = array(
                'path' => $dir_path,
                'current_perms' => $perms,
                'recommended_perms' => $recommended_perms,
                'is_writable' => $is_writable,
                'is_readable' => $is_readable,
                'status' => $status,
                'issues' => array()
            );

            // Check specific permission issues
            if ($perms > $recommended_perms) {
                $permissions_check['directories'][$dir]['issues'][] = 'Permissions too permissive';
            }
            if (!$is_readable) {
                $permissions_check['directories'][$dir]['issues'][] = 'Directory not readable';
            }
            // We no longer consider directory writability an issue on shared hosting
            // as the web server process typically runs as the file owner

            if (!empty($permissions_check['directories'][$dir]['issues'])) {
                $permissions_check['summary']['total_issues']++;
            }
        } else {
            $permissions_check['directories'][$dir] = array(
                'path' => $dir_path,
                'status' => 'critical',
                'issues' => array('Directory does not exist')
            );
            $permissions_check['summary']['critical_issues']++;
            $permissions_check['summary']['total_issues']++;
        }
    }

    // Check critical files
    foreach ($critical_files as $file => $recommended_perms) {
        $file_path = $wp_root . $file;
        
        // Special handling for wp-config.php
        if ($file === 'wp-config.php' && !file_exists($file_path)) {
            // Check parent directory for wp-config.php
            $parent_config = dirname($wp_root) . '/wp-config.php';
            if (file_exists($parent_config)) {
                // Found in parent directory, update path and continue
                $file_path = $parent_config;
                $permissions_check['files'][$file] = array(
                    'path' => $file_path,
                    'status' => 'info',
                    'message' => 'Found in parent directory (better security practice)'
                );
                continue;
            } else {
                // Not found in typical locations, provide more helpful message
                $permissions_check['files'][$file] = array(
                    'path' => $file_path,
                    'status' => 'warning',
                    'issues' => array('wp-config.php not found in standard locations. It may exist elsewhere for security reasons.')
                );
                $permissions_check['summary']['warnings']++;
                $permissions_check['summary']['total_issues']++;
                continue;
            }
        }
        
        if (file_exists($file_path)) {
            $perms = substr(sprintf('%o', fileperms($file_path)), -4);
            $is_writable = wp_is_writable($file_path);
            $is_readable = is_readable($file_path);
            
            $status = $perms === $recommended_perms ? 'optimal' : 'warning';
            if ($perms > $recommended_perms) {
                $status = 'critical';
                $permissions_check['summary']['critical_issues']++;
            } elseif ($status === 'warning') {
                $permissions_check['summary']['warnings']++;
            }

            $permissions_check['files'][$file] = array(
                'path' => $file_path,
                'current_perms' => $perms,
                'recommended_perms' => $recommended_perms,
                'is_writable' => $is_writable,
                'is_readable' => $is_readable,
                'status' => $status,
                'issues' => array()
            );

            // Check specific permission issues
            if ($perms > $recommended_perms) {
                $permissions_check['files'][$file]['issues'][] = 'Permissions too permissive';
            }
            if (!$is_readable) {
                $permissions_check['files'][$file]['issues'][] = 'File not readable';
            }
            // Only report actual permission issues for wp-config.php, not writability
            // which is normal on shared hosting environments where the web server
            // runs as the same user who owns the files

            if (!empty($permissions_check['files'][$file]['issues'])) {
                $permissions_check['summary']['total_issues']++;
            }
        } else if ($file === '.htaccess') {
            // Check server type for .htaccess relevance
            $server_type = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '';
            $is_apache = stripos($server_type, 'apache') !== false;
            $is_litespeed = stripos($server_type, 'litespeed') !== false;
            
            if ($is_apache || $is_litespeed) {
                // For Apache-based servers, .htaccess is important
                $permissions_check['files'][$file] = array(
                    'path' => $file_path,
                    'status' => 'warning',
                    'issues' => array('File does not exist - may affect URL rewriting on Apache')
                );
                $permissions_check['summary']['warnings']++;
                $permissions_check['summary']['total_issues']++;
            } else {
                // For non-Apache servers, .htaccess is irrelevant
                $permissions_check['files'][$file] = array(
                    'path' => $file_path,
                    'status' => 'info',
                    'message' => 'Missing .htaccess is normal for non-Apache servers (like Nginx or IIS)'
                );
            }
        } else {
            // Other missing critical files
            $permissions_check['files'][$file] = array(
                'path' => $file_path,
                'status' => 'critical',
                'issues' => array('File does not exist')
            );
            $permissions_check['summary']['critical_issues']++;
            $permissions_check['summary']['total_issues']++;
        }
    }
    
    // Check permissions for core PHP files
    foreach ($core_php_files as $file => $recommended_perms) {
        $file_path = $wp_root . $file;
        if (file_exists($file_path)) {
            $perms = substr(sprintf('%o', fileperms($file_path)), -4);
            $is_writable = wp_is_writable($file_path);
            $is_readable = is_readable($file_path);
            
            $status = $perms === $recommended_perms ? 'optimal' : 'warning';
            if ($perms > $recommended_perms) {
                $status = 'critical';
                $permissions_check['summary']['critical_issues']++;
            } elseif ($status === 'warning') {
                $permissions_check['summary']['warnings']++;
            }

            // Only add the file to the results if there's an issue
            if ($status !== 'optimal') {
                $permissions_check['files'][$file] = array(
                    'path' => $file_path,
                    'current_perms' => $perms,
                    'recommended_perms' => $recommended_perms,
                    'is_writable' => $is_writable,
                    'is_readable' => $is_readable,
                    'status' => $status,
                    'issues' => array()
                );
                
                // Add specific issues
                if ($perms > $recommended_perms) {
                    $permissions_check['files'][$file]['issues'][] = 'Permissions too permissive';
                }
                if (!$is_readable) {
                    $permissions_check['files'][$file]['issues'][] = 'File not readable';
                }
                
                $permissions_check['summary']['total_issues']++;
            }
        }
    }

    return $permissions_check;
}

function wpfortai_check_core_files() {
    global $wp_version;
    $results = array(
        'modified_files' => array(),
        'missing_files' => array(),
        'unknown_files' => array(),
        'summary' => array(
            'total_checked' => 0,
            'modified_count' => 0,
            'missing_count' => 0,
            'unknown_count' => 0
        ),
        'checksum_api_status' => array(
            'status' => 'pending',
            'message' => ''
        )
    );

    // Get official WordPress checksums with multiple fallback URLs
    $checksum_urls = array(
        "https://api.wordpress.org/core/checksums/1.0/?version={$wp_version}&locale=" . get_locale(),
        "https://api.wordpress.org/core/checksums/1.0/?version={$wp_version}",
        "https://api.wordpress.org/core/checksums/1.0/?version=latest"
    );

    $checksums = null;
    $successful_url = '';
    
    foreach ($checksum_urls as $url) {
        $response = wp_remote_get($url, array(
            'timeout' => 30,
            'sslverify' => true
        ));
        
        if (!is_wp_error($response)) {
            $body = wp_remote_retrieve_body($response);
            $data = json_decode($body, true);
            
            if (isset($data['checksums']) && is_array($data['checksums'])) {
                if (strpos($url, 'version=latest') !== false) {
                    $checksums = $data['checksums'];
                } else {
                    $checksums = isset($data['checksums'][$wp_version]) ? $data['checksums'][$wp_version] : null;
                }
                
                if ($checksums) {
                    $successful_url = $url;
                    break;
                }
            }
        }
    }

    if (!$checksums) {
        $results['checksum_api_status'] = array(
            'status' => 'error',
            'message' => 'Failed to fetch valid WordPress checksums. Performing limited security check.',
            'attempted_urls' => $checksum_urls
        );
        return wpfortai_perform_limited_security_check($results);
    }

    $results['checksum_api_status'] = array(
        'status' => 'success',
        'message' => 'Successfully fetched checksums from: ' . $successful_url
    );

    $wp_root = ABSPATH;
    $core_checksums = $checksums;

    // Build a map of all core files
    $core_files_map = array();
    foreach ($core_checksums as $file => $checksum) {
        $core_files_map[$file] = $checksum;
        if (strpos($file, '.js') !== false && strpos($file, '.min.js') === false) {
            $minified = str_replace('.js', '.min.js', $file);
            $core_files_map[$minified] = true;
        }
        if (strpos($file, '.css') !== false && strpos($file, '.min.css') === false) {
            $minified = str_replace('.css', '.min.css', $file);
            $core_files_map[$minified] = true;
        }
    }

    // Check core directories
    $core_dirs = array('wp-admin', 'wp-includes');
    foreach ($core_dirs as $dir) {
        $dir_path = $wp_root . $dir;
        if (!is_dir($dir_path)) {
            continue;
        }

        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dir_path, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::SELF_FIRST
        );

        foreach ($iterator as $file) {
            if (!$file->isFile()) {
                continue;
            }

            $relative_path = str_replace($wp_root, '', $file->getPathname());
            $relative_path = str_replace('\\', '/', $relative_path);
            $relative_path = ltrim($relative_path, '/');

            $results['summary']['total_checked']++;

            // Skip certain file types from checksum verification but still track them
            $is_resource = preg_match('/\.(png|gif|jpg|jpeg|ico|svg|ttf|eot|woff|woff2)$/', $relative_path);
            
            if ($is_resource) {
                if (!isset($core_files_map[$relative_path])) {
                    $results['unknown_files'][] = array(
                        'path' => $relative_path,
                        'type' => 'resource',
                        'size' => $file->getSize(),
                        'modified' => $file->getMTime()
                    );
                    $results['summary']['unknown_count']++;
                }
                continue;
            }

            // Check if this is a known core file
            if (isset($core_files_map[$relative_path])) {
                // We don't check permissions here anymore - that's done in wpfortai_check_directory_permissions
                
                // Skip checksum verification for minified files
                if (strpos($relative_path, '.min.') !== false) {
                    continue;
                }

                // Verify checksum for non-minified files
                if ($core_files_map[$relative_path] !== true) {
                    $file_contents = file_get_contents($file->getPathname());
                    $current_checksum = md5($file_contents);

                    if ($current_checksum !== $core_files_map[$relative_path]) {
                        $results['modified_files'][] = array(
                            'path' => $relative_path,
                            'type' => 'modified',
                            'severity' => wpfortai_determine_file_severity($relative_path),
                            'expected_checksum' => $core_files_map[$relative_path],
                            'current_checksum' => $current_checksum,
                            'size' => $file->getSize(),
                            'last_modified' => $file->getMTime()
                        );
                        $results['summary']['modified_count']++;
                    }
                }
            } else {
                // Skip .htaccess files as they're now handled by the file scan system
                if (basename($file->getPathname()) === '.htaccess') {
                    continue;
                }
                
                $results['unknown_files'][] = array(
                    'path' => $relative_path,
                    'type' => 'unknown',
                    'severity' => wpfortai_determine_file_severity($relative_path),
                    'size' => $file->getSize(),
                    'modified' => $file->getMTime()
                );
                $results['summary']['unknown_count']++;
            }
        }
    }

    // Check for missing core files
    // Define non-essential files that shouldn't trigger alarms when missing
    $non_essential_files = array(
        'wp-content/plugins/hello.php',           // Hello Dolly plugin (commonly removed)
        'wp-content/plugins/hello-dolly',        // Hello Dolly directory
        'wp-content/plugins/akismet/akismet.php', // Akismet may be removed
        'license.txt',                           // License file isn't critical
        'readme.html',                           // Readme file isn't critical
        'wp-config-sample.php',                  // Sample config isn't critical
    );
    
    // Patterns for files that shouldn't be reported as missing
    $non_critical_patterns = array(
        // Bundled plugins that are often removed
        '#^wp-content/plugins/akismet/#i',            // All Akismet plugin files
        '#^wp-content/plugins/hello\.php#i',         // Hello Dolly plugin
        
        // Theme files and other assets
        '#wp-content/themes/.*/assets/fonts/#i',      // Theme font files
        '#wp-content/themes/.*/assets/images/#i',     // Theme images
        '#wp-content/themes/.*/assets/css/#i',        // Theme CSS
        '#wp-content/themes/.*/assets/js/#i',         // Theme JS
        '#wp-content/themes/twenty[^/]+/#i',          // Default WordPress themes
        
        // Font and asset files
        '#\.ttf(\.woff2?)?$#i',                       // Font files (.ttf, .ttf.woff, .ttf.woff2)
        '#\.woff2?$#i',                                // Font files (.woff, .woff2)
        '#\.eot$#i',                                  // Font files (.eot)
        '#\.svg$#i',                                  // SVG files
        
        // Documentation and language files
        '#readme\-.*\.txt$#i',                        // Various readme files
        '#\.po$#i',                                   // Translation files
        '#\.mo$#i',                                   // Translation files
    );
    
    foreach ($core_files_map as $file => $checksum) {
        if ($checksum !== true) { // Skip minified versions
            // Skip non-essential files
            if (in_array($file, $non_essential_files)) {
                continue;
            }
            
            // Skip files matching non-critical patterns (fonts, theme assets, etc.)
            $is_non_critical = false;
            foreach ($non_critical_patterns as $pattern) {
                if (preg_match($pattern, $file)) {
                    $is_non_critical = true;
                    break;
                }
            }
            
            if ($is_non_critical) {
                continue;
            }
            
            $file_path = $wp_root . $file;
            if (!file_exists($file_path)) {
                // Check if this is a critical file
                $is_critical = !preg_match('/(readme\.html|license\.txt|\.md$)/i', $file);
                
                // Only add to results if it's important enough to report
                if ($is_critical) {
                    $results['missing_files'][] = array(
                        'path' => $file,
                        'type' => 'missing',
                        'severity' => wpfortai_determine_file_severity($file)
                    );
                    $results['summary']['missing_count']++;
                }
            }
        }
    }

    // Sort results for better readability
    usort($results['modified_files'], function($a, $b) {
        return strcmp($a['path'], $b['path']);
    });
    usort($results['unknown_files'], function($a, $b) {
        return strcmp($a['path'], $b['path']);
    });

    return $results;
}

function wpfortai_determine_file_severity($file_path) {
    $critical_patterns = array(
        '/\.php$/',
        '/wp-includes\/functions\.php/',
        '/wp-includes\/pluggable\.php/',
        '/wp-includes\/capabilities\.php/',
        '/wp-includes\/user\.php/',
        '/wp-admin\/includes/',
        '/wp-login\.php/'
    );

    $warning_patterns = array(
        '/\.js$/',
        '/\.css$/',
        '/wp-includes\/js/',
        '/wp-includes\/css/'
    );

    foreach ($critical_patterns as $pattern) {
        if (preg_match($pattern, $file_path)) {
            return 'critical';
        }
    }

    foreach ($warning_patterns as $pattern) {
        if (preg_match($pattern, $file_path)) {
            return 'warning';
        }
    }

    return 'info';
}

function wpfortai_perform_limited_security_check($results) {
    $wp_root = ABSPATH;
    $critical_files = array(
        // Core system files
        'wp-admin/index.php',
        'wp-admin/admin.php',
        'wp-admin/admin-ajax.php',
        'wp-admin/admin-post.php',
        'wp-admin/async-upload.php',
        'wp-admin/comment.php',
        'wp-admin/edit.php',
        'wp-admin/includes/admin.php',
        'wp-admin/includes/ajax-actions.php',
        'wp-admin/includes/class-wp-posts-list-table.php',
        'wp-admin/includes/update.php',
        'wp-admin/includes/upgrade.php',
        'wp-admin/post.php',
        'wp-admin/update.php',
        'wp-login.php',
        
        // Core includes
        'wp-includes/version.php',
        'wp-includes/functions.php',
        'wp-includes/pluggable.php',
        'wp-includes/capabilities.php',
        'wp-includes/class-wp-roles.php',
        'wp-includes/class-wp-query.php',
        'wp-includes/class-wp-post.php',
        'wp-includes/class-wp-hook.php',
        'wp-includes/plugin.php',
        'wp-includes/user.php',
        'wp-includes/general-template.php',
        'wp-includes/rewrite.php',
        'wp-includes/rest-api.php',
        'wp-includes/theme.php',
        'wp-includes/update.php'
    );

    foreach ($critical_files as $file) {
        $file_path = $wp_root . $file;
        if (!file_exists($file_path)) {
            $results['missing_files'][] = array(
                'path' => $file,
                'type' => 'critical',
                'message' => 'Critical WordPress core file is missing'
            );
            $results['summary']['missing_count']++;
        } else {
            // Basic integrity checks
            $file_perms = substr(sprintf('%o', fileperms($file_path)), -4);
            $is_writable = wp_is_writable($file_path);
            
            if ($file_perms !== '0644' || $is_writable) {
                $results['modified_files'][] = array(
                    'path' => $file,
                    'type' => 'permissions',
                    'severity' => 'warning',
                    'current_perms' => $file_perms,
                    'is_writable' => $is_writable,
                    'recommended_perms' => '0644'
                );
                $results['summary']['modified_count']++;
            }
        }
    }

    // Check for suspicious files in core directories
    // Note: .htaccess detection removed as it's now handled by the file scanning system
    $suspicious_patterns = array(
        '\.php$' => array('wp-content/uploads'),
        '(eval|base64_decode|system|exec|shell_exec)' => array('wp-content'),
        'php\.ini$' => array('wp-content', 'wp-includes')
    );

    foreach ($suspicious_patterns as $pattern => $dirs) {
        foreach ($dirs as $dir) {
            $dir_path = $wp_root . $dir;
            if (is_dir($dir_path)) {
                $iterator = new RecursiveIteratorIterator(
                    new RecursiveDirectoryIterator($dir_path, RecursiveDirectoryIterator::SKIP_DOTS),
                    RecursiveIteratorIterator::SELF_FIRST
                );

                foreach ($iterator as $file) {
                    if ($file->isFile() && preg_match('/' . $pattern . '/i', $file->getFilename())) {
                        $relative_path = str_replace($wp_root, '', $file->getPathname());
                        $results['unknown_files'][] = array(
                            'path' => $relative_path,
                            'type' => 'suspicious',
                            'pattern_matched' => $pattern,
                            'size' => $file->getSize(),
                            'modified' => $file->getMTime()
                        );
                        $results['summary']['unknown_count']++;
                    }
                }
            }
        }
    }

    return $results;
}

// Register the endpoint
add_action('rest_api_init', function () {
    register_rest_route('wpsec/v1', '/core-check', array(
        'methods' => 'GET',
        'callback' => 'wpfortai_core_check_endpoint',
        'permission_callback' => '__return_true' // Authentication handled by global middleware
    ));
});
