<?php
/**
 * Tests for MLF_Font_Registry class.
 *
 * @package Maple_Local_Fonts
 */

/**
 * Class Test_MLF_Font_Registry
 *
 * @covers MLF_Font_Registry
 */
class Test_MLF_Font_Registry extends WP_UnitTestCase {

    /**
     * Font registry instance.
     *
     * @var MLF_Font_Registry
     */
    private $registry;

    /**
     * Set up test fixtures.
     */
    public function set_up() {
        parent::set_up();
        $this->registry = new MLF_Font_Registry();

        // Clear font cache
        delete_transient('mlf_imported_fonts_list');
    }

    /**
     * Clean up after tests.
     */
    public function tear_down() {
        // Clean up any test fonts
        $fonts = get_posts([
            'post_type'      => 'wp_font_family',
            'posts_per_page' => -1,
            'meta_key'       => '_mlf_imported',
            'meta_value'     => '1',
            'fields'         => 'ids',
        ]);

        foreach ($fonts as $font_id) {
            wp_delete_post($font_id, true);
        }

        delete_transient('mlf_imported_fonts_list');
        parent::tear_down();
    }

    /**
     * Test that get_imported_fonts returns empty array when no fonts installed.
     */
    public function test_get_imported_fonts_empty() {
        $fonts = $this->registry->get_imported_fonts();
        $this->assertIsArray($fonts);
        $this->assertEmpty($fonts);
    }

    /**
     * Test font registration.
     */
    public function test_register_font() {
        $font_name = 'Test Font';
        $font_slug = 'test-font';
        $files = [
            [
                'path'   => '/tmp/test-font_normal_400.woff2',
                'weight' => '400',
                'style'  => 'normal',
            ],
        ];

        // Create a dummy file for the test
        file_put_contents($files[0]['path'], 'wOF2dummy');

        $result = $this->registry->register_font($font_name, $font_slug, $files);

        $this->assertIsInt($result);
        $this->assertGreaterThan(0, $result);

        // Verify font was registered
        $font = get_post($result);
        $this->assertEquals('wp_font_family', $font->post_type);
        $this->assertEquals($font_name, $font->post_title);

        // Clean up
        unlink($files[0]['path']);
    }

    /**
     * Test that duplicate fonts are rejected.
     */
    public function test_register_font_duplicate() {
        $font_name = 'Duplicate Font';
        $font_slug = 'duplicate-font';
        $files = [
            [
                'path'   => '/tmp/duplicate-font_normal_400.woff2',
                'weight' => '400',
                'style'  => 'normal',
            ],
        ];

        file_put_contents($files[0]['path'], 'wOF2dummy');

        // Register first time
        $result1 = $this->registry->register_font($font_name, $font_slug, $files);
        $this->assertIsInt($result1);

        // Try to register again
        $result2 = $this->registry->register_font($font_name, $font_slug, $files);
        $this->assertWPError($result2);
        $this->assertEquals('font_exists', $result2->get_error_code());

        // Clean up
        unlink($files[0]['path']);
    }

    /**
     * Test get_imported_fonts returns registered fonts.
     */
    public function test_get_imported_fonts_returns_fonts() {
        $font_name = 'Listed Font';
        $font_slug = 'listed-font';
        $files = [
            [
                'path'   => '/tmp/listed-font_normal_400.woff2',
                'weight' => '400',
                'style'  => 'normal',
            ],
            [
                'path'   => '/tmp/listed-font_normal_700.woff2',
                'weight' => '700',
                'style'  => 'normal',
            ],
        ];

        foreach ($files as $file) {
            file_put_contents($file['path'], 'wOF2dummy');
        }

        $font_id = $this->registry->register_font($font_name, $font_slug, $files);

        // Clear cache to test fresh retrieval
        delete_transient('mlf_imported_fonts_list');

        $fonts = $this->registry->get_imported_fonts();

        $this->assertCount(1, $fonts);
        $this->assertEquals($font_id, $fonts[0]['id']);
        $this->assertEquals($font_name, $fonts[0]['name']);
        $this->assertEquals($font_slug, $fonts[0]['slug']);
        $this->assertCount(2, $fonts[0]['variants']);

        // Clean up
        foreach ($files as $file) {
            unlink($file['path']);
        }
    }

    /**
     * Test font deletion.
     */
    public function test_delete_font() {
        $font_name = 'Delete Font';
        $font_slug = 'delete-font';
        $files = [
            [
                'path'   => '/tmp/delete-font_normal_400.woff2',
                'weight' => '400',
                'style'  => 'normal',
            ],
        ];

        file_put_contents($files[0]['path'], 'wOF2dummy');

        $font_id = $this->registry->register_font($font_name, $font_slug, $files);

        // Delete the font
        $result = $this->registry->delete_font($font_id);
        $this->assertTrue($result);

        // Verify font is gone
        $font = get_post($font_id);
        $this->assertNull($font);
    }

    /**
     * Test delete_font rejects non-existent fonts.
     */
    public function test_delete_font_not_found() {
        $result = $this->registry->delete_font(99999);
        $this->assertWPError($result);
        $this->assertEquals('not_found', $result->get_error_code());
    }

    /**
     * Test delete_font rejects fonts not imported by plugin.
     */
    public function test_delete_font_not_ours() {
        // Create a font family post without our meta
        $font_id = wp_insert_post([
            'post_type'   => 'wp_font_family',
            'post_title'  => 'Theme Font',
            'post_status' => 'publish',
        ]);

        $result = $this->registry->delete_font($font_id);
        $this->assertWPError($result);
        $this->assertEquals('not_ours', $result->get_error_code());

        // Clean up
        wp_delete_post($font_id, true);
    }

    /**
     * Test that cache is cleared on register.
     */
    public function test_cache_cleared_on_register() {
        // Set a dummy cache
        set_transient('mlf_imported_fonts_list', ['cached' => true], 300);

        $font_name = 'Cache Test Font';
        $font_slug = 'cache-test-font';
        $files = [
            [
                'path'   => '/tmp/cache-test-font_normal_400.woff2',
                'weight' => '400',
                'style'  => 'normal',
            ],
        ];

        file_put_contents($files[0]['path'], 'wOF2dummy');

        $this->registry->register_font($font_name, $font_slug, $files);

        // Cache should be cleared
        $cached = get_transient('mlf_imported_fonts_list');
        $this->assertFalse($cached);

        // Clean up
        unlink($files[0]['path']);
    }

    /**
     * Test that cache is cleared on delete.
     */
    public function test_cache_cleared_on_delete() {
        $font_name = 'Cache Delete Font';
        $font_slug = 'cache-delete-font';
        $files = [
            [
                'path'   => '/tmp/cache-delete-font_normal_400.woff2',
                'weight' => '400',
                'style'  => 'normal',
            ],
        ];

        file_put_contents($files[0]['path'], 'wOF2dummy');

        $font_id = $this->registry->register_font($font_name, $font_slug, $files);

        // Set a dummy cache
        set_transient('mlf_imported_fonts_list', ['cached' => true], 300);

        $this->registry->delete_font($font_id);

        // Cache should be cleared
        $cached = get_transient('mlf_imported_fonts_list');
        $this->assertFalse($cached);
    }

    /**
     * Test font_exists method.
     */
    public function test_font_exists() {
        $font_name = 'Exists Font';
        $font_slug = 'exists-font';
        $files = [
            [
                'path'   => '/tmp/exists-font_normal_400.woff2',
                'weight' => '400',
                'style'  => 'normal',
            ],
        ];

        file_put_contents($files[0]['path'], 'wOF2dummy');

        // Before registration
        $this->assertFalse($this->registry->font_exists($font_slug));

        // After registration
        $this->registry->register_font($font_name, $font_slug, $files);
        $this->assertTrue($this->registry->font_exists($font_slug));

        // Clean up
        unlink($files[0]['path']);
    }
}
