<?php
/**
 * Uninstall script for Maple Local Fonts.
 *
 * This file is executed when the plugin is deleted from WordPress.
 * It removes all fonts imported by this plugin and cleans up any data.
 *
 * @package Maple_Local_Fonts
 */

// If uninstall not called from WordPress, exit.
if (!defined('WP_UNINSTALL_PLUGIN')) {
    exit;
}

/**
 * Clean up all plugin data on uninstall.
 *
 * Uses batched processing to prevent memory exhaustion on sites with many fonts.
 */
function mlf_uninstall() {
    $font_dir = wp_get_font_dir();
    $batch_size = 50; // Process 50 fonts at a time to prevent memory issues
    $processed = 0;
    $max_iterations = 100; // Safety limit: max 5000 fonts (100 × 50)

    // Process fonts in batches
    for ($i = 0; $i < $max_iterations; $i++) {
        $fonts = get_posts([
            'post_type'      => 'wp_font_family',
            'posts_per_page' => $batch_size,
            'post_status'    => 'any',
            'meta_key'       => '_mlf_imported',
            'meta_value'     => '1',
            'fields'         => 'ids', // Only get IDs for memory efficiency
        ]);

        // No more fonts to process
        if (empty($fonts)) {
            break;
        }

        // Get all font faces for this batch in a single query
        $all_faces = get_posts([
            'post_type'       => 'wp_font_face',
            'posts_per_page'  => $batch_size * 20, // Max ~20 faces per font
            'post_status'     => 'any',
            'post_parent__in' => $fonts,
        ]);

        // Delete font face files and posts
        foreach ($all_faces as $face) {
            $settings = json_decode($face->post_content, true);

            if (isset($settings['src'])) {
                // Convert file:. URL to path
                $src = $settings['src'];
                $src = str_replace('file:./', '', $src);
                $file_path = trailingslashit($font_dir['path']) . basename($src);

                // Validate path and extension before deletion
                if (mlf_uninstall_validate_font_path($file_path, $font_dir)
                    && pathinfo($file_path, PATHINFO_EXTENSION) === 'woff2'
                    && file_exists($file_path)) {
                    wp_delete_file($file_path);
                }
            }

            wp_delete_post($face->ID, true);
        }

        // Delete family posts
        foreach ($fonts as $font_id) {
            wp_delete_post($font_id, true);
        }

        $processed += count($fonts);

        // Free memory
        unset($fonts, $all_faces);

        // If we got fewer than batch_size, we're done
        if (count($fonts) < $batch_size) {
            break;
        }
    }

    // Clear caches
    delete_transient('wp_font_library_fonts');
    delete_transient('mlf_imported_fonts_list');
}

/**
 * Validate that a path is within the WordPress fonts directory.
 *
 * @param string $path     Full path to validate.
 * @param array  $font_dir Font directory info.
 * @return bool True if path is safe, false otherwise.
 */
function mlf_uninstall_validate_font_path($path, $font_dir) {
    $fonts_path = wp_normalize_path(trailingslashit($font_dir['path']));

    // Resolve to real path (handles ../ etc)
    $real_path = realpath($path);

    // If realpath fails, file doesn't exist yet - validate the directory
    if ($real_path === false) {
        $dir = dirname($path);
        $real_dir = realpath($dir);
        if ($real_dir === false) {
            return false;
        }
        $real_path = wp_normalize_path($real_dir . '/' . basename($path));
    } else {
        $real_path = wp_normalize_path($real_path);
    }

    // Must be within fonts directory
    return strpos($real_path, $fonts_path) === 0;
}

// Run uninstall
mlf_uninstall();
