<?php
// Exit if accessed directly
if (!defined('ABSPATH')) exit;

WP_CLI::add_command('rdg_blocks', 'RDG_Blocks_CLI');

class RDG_Blocks_CLI extends WP_CLI_Command
{
    private $cache_dir;

    public function __construct()
    {
        $this->cache_dir = wp_upload_dir()['basedir'].'/'.RDGBLOCKS_NAME_SLUG.'/';
    }

    public function details()
    {
        WP_CLI::line(sprintf(__('Plugin name: %s'), RDGBLOCKS_NAME));
        WP_CLI::line(sprintf(__('Plugin version: %s'), RDGBLOCKS_VERSION));
    }

    public function status_cache() {
        if (!file_exists($this->cache_dir)) {
            WP_CLI::line(sprintf(__('Directory does not exist: %s'), $this->cache_dir));
    
            return;
        }
    
        $cache_list = scandir($this->cache_dir);

        WP_CLI::line(sprintf(__('Cache files: %s'), count($cache_list)));
    }

    public function clear_cache()
    {
        if (!file_exists($this->cache_dir)) {
            WP_CLI::line(sprintf(__('Directory does not exist: %s'), $this->cache_dir));
    
            return;
        }
    
        $cache_list = scandir($this->cache_dir);
        $files_deletes = 0;
    
        foreach ($cache_list as $cache_file) {
            if ($cache_file != '.' && $cache_file != '..' && !is_dir($this->cache_dir.$cache_file)) {
                $file_parts = explode('-',$cache_file);
    
                # Validate if the cache file name contains the minimum elements.
                if (is_array($file_parts) && count($file_parts) >= 5) {
                    $extension = $file_parts[count($file_parts) - 1];
                    $block_id = $file_parts[count($file_parts) - 2];
                    $prefix_block = $file_parts[count($file_parts) - 3];
                    $post_id = $file_parts[count($file_parts) - 4];
    
                    # Validate if the cache file name contains the minimum information.
                    if ($extension == 'cache.log' && $prefix_block == 'block' && !empty($block_id) && !empty($post_id)) {
                        $post = get_post($post_id);
    
                        # Validate if the post/page exists
                        if ($post) {
                            # Validate if the post/page is published.
                            if ($post->post_status != 'publish') {
                                $delete = $this->delete_cache($this->cache_dir.$cache_file);

                                if ($delete) {
                                    $files_deletes++;

                                    error_log(print_r([
                                        'message' => 'The cache file refers to an unpublished post.',
                                        'cache_file' => $this->cache_dir.$cache_file,
                                    ], true));
                                }

                                continue;
                            }
    
                            # Validate if the post/page still contains a block associated with the cache file.
                            if (!str_contains($post->post_content, $block_id)) {
                                $delete = $this->delete_cache($this->cache_dir.$cache_file);

                                if ($delete) {
                                    $files_deletes++;

                                    error_log(print_r([
                                        'message' => 'The cache file is no longer used by a block in the post.',
                                        'cache_file' => $this->cache_dir.$cache_file,
                                    ], true));
                                }

                                continue;
                            }
                        } else {
                            $delete = $this->delete_cache($this->cache_dir.$cache_file);

                            if ($delete) {
                                $files_deletes++;

                                error_log(print_r([
                                    'message' => 'The cache file refers to a post that does not exist.',
                                    'cache_file' => $this->cache_dir.$cache_file,
                                ], true));
                            }
                        }
                    } else {
                        $delete = $this->delete_cache($this->cache_dir.$cache_file);

                        if ($delete) {
                            $files_deletes++;

                            error_log(print_r([
                                'message' => 'Invalid cache name format.',
                                'cache_file' => $this->cache_dir.$cache_file,
                            ], true));
                        }
                    }
                } else {
                    $delete = $this->delete_cache($this->cache_dir.$cache_file);

                    if ($delete) {
                        $files_deletes++;

                        error_log(print_r([
                            'message' => 'Invalid cache name format.',
                            'cache_file' => $this->cache_dir.$cache_file,
                        ], true));
                    }
                }
            }
        }

        error_log(sprintf(__('RDG_Blocks_CLI: Deleted cache files: %s'), $files_deletes));

        WP_CLI::line(sprintf(__('Deleted cache files: %s'), $files_deletes));
    }

    public function delete_all()
    {
        if (!file_exists($this->cache_dir)) {
            WP_CLI::line(sprintf(__('Directory does not exist: %s'), $this->cache_dir));
    
            return;
        }
    
        $cache_list = scandir($this->cache_dir);
        $files_deletes = 0;
    
        foreach ($cache_list as $cache_file) {
            if ($cache_file != '.' && $cache_file != '..' && !is_dir($this->cache_dir.$cache_file)) {
                $delete = $this->delete_cache($this->cache_dir.$cache_file);
                if ($delete) $files_deletes++;
            }
        }

        WP_CLI::line(sprintf(__('Deleted cache files: %s'), $files_deletes));
    }

    private function delete_cache($cache_file) {
        try {
            unlink($cache_file);

            return true;
        } catch (\Exception $exception) {
            error_log(print_r([
                'message' => 'Error trying to clear cache file.',
                'exception' => $exception->getMessage(),
                'cache_file' => $cache_file,
            ], true));
        }

        return false;
    }
}
