#!/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

use cPstrict;

use FindBin;
use lib "$FindBin::Bin/../lib";

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 Mock::Cpanel::Logger;

use Test::Cpanel::Policy testing => 'Common::Plugins::Setup::Steps';

use Common::Plugins::Setup::Steps ();

subtest 'run_steps input validation' => sub {
    like( dies { Common::Plugins::Setup::Steps::run_steps() },                        qr/Too few arguments for subroutine/,           'run_steps() with no arguments should die' );
    like( dies { Common::Plugins::Setup::Steps::run_steps('') },                      qr//,                                           'run_steps() with a non-reference argument should die' );
    like( dies { Common::Plugins::Setup::Steps::run_steps('foo') },                   qr/No steps to run/,                            'run_steps() with a non-reference argument should die' );
    like( dies { Common::Plugins::Setup::Steps::run_steps( 'foo', 'do_something' ) }, qr{Steps must have an even number of elements}, 'run_steps() with a slurpy argumment initialied with a odd length list should die' );
};

subtest 'run_steps with one item' => sub {
    Mock::Cpanel::Logger::clear_all();
    my ( $got_ok, $got_errors ) = Common::Plugins::Setup::Steps::run_steps( 'foo', 'true' => {} );
    is( $got_ok,     !!1, 'return true value when the one step succeeds' );
    is( $got_errors, [],  'return empty array when the one step succeeds' );

    Mock::Cpanel::Logger::clear_all();
    ( $got_ok, $got_errors ) = Common::Plugins::Setup::Steps::run_steps( 'foo', 'false' => {} );
    is( $got_ok, !!0, 'return false value when the one step fails' );
    like(
        $got_errors, [
            qr/The system failed to setup foo while running false./
        ], 'return empty array when the one step fails'
    );

    Mock::Cpanel::Logger::clear_all();
};

subtest 'run_steps with two item' => sub {
    Mock::Cpanel::Logger::clear_all();
    my ( $got_ok, $got_errors ) = Common::Plugins::Setup::Steps::run_steps( 'foo', 'true' => {}, 'true' => {} );
    is( $got_ok,     !!1, 'return true value when the one step succeeds' );
    is( $got_errors, [],  'return empty array when the one step succeeds' );

    Mock::Cpanel::Logger::clear_all();
    ( $got_ok, $got_errors ) = Common::Plugins::Setup::Steps::run_steps( 'foo', 'true' => {}, 'false' => {} );
    is( $got_ok, !!0, 'return false value when the one step succeeds' );
    like(
        $got_errors, [
            qr/The system failed to setup foo while running false./
        ], 'return empty array when the one step succeeds'
    );

    Mock::Cpanel::Logger::clear_all();
    ( $got_ok, $got_errors ) = Common::Plugins::Setup::Steps::run_steps( 'foo', 'false' => {}, 'true' => {} );
    is( $got_ok, !!0, 'return false value when the one step succeeds' );
    like(
        $got_errors, [
            qr/The system failed to setup foo while running false./
        ], 'return empty array when the one step succeeds'
    );

    Mock::Cpanel::Logger::clear_all();
    ( $got_ok, $got_errors ) = Common::Plugins::Setup::Steps::run_steps( 'foo', 'false' => {}, 'false' => {} );
    is( $got_ok, !!0, 'return false value when the one step succeeds' );
    like(
        $got_errors,
        [
            qr/The system failed to setup foo while running false./,
            qr/The system failed to setup foo while running false./,
        ],
        'return empty array when the one step succeeds'
    );

    Mock::Cpanel::Logger::clear_all();
};

subtest 'run_steps message logs message' => sub {
    Mock::Cpanel::Logger::clear_all();
    my ( $got_ok, $got_errors ) = Common::Plugins::Setup::Steps::run_steps( 'foo', 'true' => { message => "hello" } );
    is( $got_ok,     !!1, 'return true value when the one step succeeds' );
    is( $got_errors, [],  'return empty array when the one step succeeds' );
    my $got_messages = Mock::Cpanel::Logger::get_messages('info');
    like(
        $got_messages->[0]{message},
        qr/hello/,
        'log message when message is provided'
    ) or diag explain $got_messages;
    Mock::Cpanel::Logger::clear_all();
};

subtest 'run_steps command that take arguments' => sub {
    Mock::Cpanel::Logger::clear_all();
    my ( $got_ok, $got_errors ) = Common::Plugins::Setup::Steps::run_steps( 'foo', 'echo' => { args => [ "-n", "-E", 'hello\nworld' ] } );
    is( $got_ok,     !!1, 'return true value when the one step succeeds' );
    is( $got_errors, [],  'return empty array when the one step succeeds' );
    my $got_messages = Mock::Cpanel::Logger::get_messages('info');
    like(
        $got_messages->[0]{message},
        qr/Output: hello\\nworld/,
        'output property formatted by arguments verify they are passed correctly.'
    ) or diag explain $got_messages;
    Mock::Cpanel::Logger::clear_all();
};

done_testing;
