#!/usr/local/cpanel/3rdparty/bin/perl -w

#                                      Copyright 2025 WebPros International, LLC
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

package Cpanel::Plugins::Components::example::app::Example1;

use cPstrict;
use Moo;

extends 'Cpanel::Plugins::Components::Base';

has '+markup' => (
    default => 'p1',
);

has '+priority' => (
    default => 2,
);

has '+slot' => (
    default => 'default',
);

sub __set_markup ( $self, $markup ) {
    $self->{markup} = $markup;
}

package Cpanel::Plugins::Components::example::app::Example2;

use cPstrict;
use Moo;

extends 'Cpanel::Plugins::Components::Base';
with 'Cpanel::Plugins::Components::Role::Template';

has '+markup' => (
    default => '[%a%]p1[%b%]',
);

has '+process' => (
    default => sub { \1 },
);

has '+slot' => (
    default => 'default',
);

use cPstrict;

use Test2::V0;
use Test2::Tools::Explain;
use Test2::Plugin::NoWarnings;
use Test2::Tools::Subtest;
use Test2::Tools::Exception;

use Test::MockModule qw/strict/;
use Test::MockFile   qw/strict/;

use Test::Cpanel::Policy testing => 'Cpanel::Template::Plugin::Components';

use Cpanel::Template::Plugin::Components ();

subtest 'get_components' => sub {
    my $mock_loader = Test::MockModule->new('Cpanel::Plugins::Components');
    $mock_loader->redefine(
        get_components => sub ( $app, $key ) {
            return { default => [ Cpanel::Plugins::Components::example::app::Example1->new() ] };
        }
    );

    my $context    = {};
    my $plugin     = Cpanel::Template::Plugin::Components->new($context);
    my $components = $plugin->get_components( "fake", "app" );

    is $components, {
        default => [
            object { call markup => 'p1'; },
        ]
      },
      "We got the expected components";

    $components->{default}[0]->__set_markup('p2');

    $components = $plugin->get_components( "fake", "app" );
    is $components, {
        default => [
            object { call markup => 'p2'; },
        ]
      },
      "We got the same instance of the component";

    $plugin->flush_cache();
    $components = $plugin->get_components( "fake", "app" );
    is $components, {
        default => [
            object { call markup => 'p1'; },
        ]
      },
      "Cache successfully flushed.";
};

subtest 'has_components_for' => sub {
    my $mock_loader = Test::MockModule->new('Cpanel::Plugins::Components');
    $mock_loader->redefine(
        get_components => sub ( $app, $key ) {
            return { default => [ $key eq "feature1" ? ( Cpanel::Plugins::Components::example::app::Example1->new() ) : () ] };
        }
    );

    my $context = {};
    my $plugin  = Cpanel::Template::Plugin::Components->new($context);

    my $has_components = $plugin->has_components_for( "app", "feature1", "default" );
    ok $has_components, "True when component available";

    $has_components = $plugin->has_components_for( "app", "feature2", "default" );
    ok !$has_components, "False when component not found";
};

subtest 'render_component' => sub {
    subtest 'when the markup does not include tt syntax' => sub {

        my $mock_loader = Test::MockModule->new('Cpanel::Plugins::Components');
        $mock_loader->redefine(
            get_components => sub ( $app, $key ) {
                return { default => [ Cpanel::Plugins::Components::example::app::Example1->new() ] };
            }
        );

        my $context = {};
        my $plugin  = Cpanel::Template::Plugin::Components->new($context);
        $plugin->flush_cache();

        my $components = $plugin->get_components( "fake", "app" );

        foreach my $component ( $components->{default}->@* ) {
            my $output = $plugin->render_component( $component, {} );
            is $output, 'p1', "Renders expected output: $output";
        }

    };

    subtest 'when the markup include tt syntax to process' => sub {

        my $mock_loader = Test::MockModule->new('Cpanel::Plugins::Components');
        $mock_loader->redefine(
            get_components => sub ( $app, $key ) {
                return { default => [ Cpanel::Plugins::Components::example::app::Example2->new() ] };
            }
        );

        my $context = {};
        my $plugin  = Cpanel::Template::Plugin::Components->new($context);
        $plugin->flush_cache();

        my $components = $plugin->get_components( "fake", "app" );

        foreach my $component ( $components->{default}->@* ) {
            my $output = $plugin->render_component( $component, { a => '<div>', b => '</div>' } );
            is $output, '<div>p1</div>', "Renders expanded template: $output";
        }
    };
};

done_testing;
