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

#                                      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 Test::Cpanel::Policy;

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

use Test::MockModule;
use Test::MockFile;
use Cpanel::JSON;

BEGIN {
    $INC{'Cpanel/Plugins/Components/Rules.pm'}             = 1;
    $INC{'Cpanel/Plugins/Components/Rules/Util/NVData.pm'} = 1;
    $INC{'Cpanel/Plugins/Components/Rules/CompanyId.pm'}   = 1;

    $INC{'Cpanel/Server/Type.pm'} = 1;
    package Cpanel::Server::Type;
    sub get_products { return { 'cometbackup' => 1 }; }

    $INC{'Cpanel/PwCache.pm'} = 1;
    package Cpanel::PwCache;
    sub new { return bless {}, shift; }

    $INC{'Cpanel/Config/Users.pm'} = 1;
    package Cpanel::Config::Users;
    sub getcpusers { return qw(user1 user2 user3); }

    $INC{'Whostmgr/CometBackup/Setup.pm'} = 1;
    package Whostmgr::CometBackup::Setup;
    our @EXPORT = qw(is_comet_agent_installed is_agent_logged_in setup_comet_agent install_comet_agent);
    sub is_comet_agent_installed { return 0; }
    sub is_agent_logged_in       { return 0; }
    sub setup_comet_agent        { return 1; }
    sub install_comet_agent      { return 1; }

    $INC{'Whostmgr/CometBackup/AgentManager.pm'} = 1;
    package Whostmgr::CometBackup::AgentManager;
    our @EXPORT = qw(get_status start);
    sub get_status { return ( 1, 'active' ); }
    sub start      { return ( 1, '' ); }

    $INC{'Whostmgr/CometBackup/CometBackupAPI.pm'} = 1;
    package Whostmgr::CometBackup::CometBackupAPI;
    sub new  { return bless {}, shift; }
    sub call { return {}; }

    $INC{'Whostmgr/CometBackup/Constants.pm'} = 1;
    package Whostmgr::CometBackup::Constants;
    sub get_text_log_file_path { return '/var/log/comet.log'; }

    $INC{'Whostmgr/API/1/Utils.pm'} = 1;
    package Whostmgr::API::1::Utils;
    sub set_metadata_ok    { $_[0]->{result} = 1; }
    sub set_metadata_not_ok { $_[0]->{result} = 0; }

    $INC{'Whostmgr/CometBackup/RestoreRunLogs.pm'} = 1;
    package Whostmgr::CometBackup::RestoreRunLogs;
    sub new { return bless {}, shift; }
    sub get_restore_history { return (); }
}

use Whostmgr::API::1::CometBackup ();

my @mock_files = (
    Test::MockFile->file('/usr/local/cpanel/logs/error_log'),
    Test::MockFile->file('/var/cpanel/server_locale'),
);

subtest 'list_restore_history - missing JSON parameter' => sub {
    my $metadata = {};
    my $args     = {};

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    is( $result->{history}, [], 'History is empty array' );
    is( $result->{total_entries}, 0, 'Total entries is 0' );
};

subtest 'list_restore_history - empty history' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( {} ) };

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    is( $metadata->{result}, 1, 'Metadata result is ok' );
    is( ref $result->{history}, 'ARRAY', 'History is an array' );
    is( scalar @{ $result->{history} }, 0, 'History is empty' );
    is( $result->{total_entries}, 0, 'Total entries is 0' );
};

subtest 'list_restore_history - with limit parameter' => sub {
    my $limit_received;
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_history' => sub {
        my ( $self, %params ) = @_;
        $limit_received = $params{limit};
        return ();
    } );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { limit => 25 } ) };

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    is( $limit_received, 25, 'Limit parameter passed correctly' );
    is( $metadata->{result}, 1, 'Metadata result is ok' );
};

subtest 'list_restore_history - default limit is 50' => sub {
    my $limit_received;
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_history' => sub {
        my ( $self, %params ) = @_;
        $limit_received = $params{limit};
        return ();
    } );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( {} ) };

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    is( $limit_received, 50, 'Default limit is 50' );
};

subtest 'list_restore_history - with status filter' => sub {
    my $status_received;
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_history' => sub {
        my ( $self, %params ) = @_;
        $status_received = $params{status};
        return ();
    } );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { status => 'completed' } ) };

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    is( $status_received, 'completed', 'Status filter passed correctly' );
};

subtest 'list_restore_history - with initiated_by filter' => sub {
    my $initiated_by_received;
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_history' => sub {
        my ( $self, %params ) = @_;
        $initiated_by_received = $params{initiated_by};
        return ();
    } );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { initiated_by => 'admin' } ) };

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    is( $initiated_by_received, 'admin', 'initiated_by filter passed correctly' );
};

subtest 'list_restore_history - with date filters' => sub {
    my %params_received;
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_history' => sub {
        my ( $self, %params ) = @_;
        %params_received = %params;
        return ();
    } );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        start_date => '2024-01-01',
        end_date   => '2024-01-31'
    } ) };

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    is( $params_received{start_date}, '2024-01-01', 'start_date filter passed' );
    is( $params_received{end_date}, '2024-01-31', 'end_date filter passed' );
};

subtest 'list_restore_history - response structure' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( {} ) };

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    ok( exists $result->{history}, 'Response has history key' );
    ok( exists $result->{total_entries}, 'Response has total_entries key' );
    ok( exists $result->{filters_applied}, 'Response has filters_applied key' );
    is( ref $result->{history}, 'ARRAY', 'History is array' );
    is( ref $result->{filters_applied}, 'HASH', 'filters_applied is hash' );
};

subtest 'list_restore_history - with restore entries' => sub {
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_history' => sub {
        return (
            {
                job_uuid     => 'restore-1',
                restore_type => 'full',
                users        => ['user1'],
                status       => 'completed',
                initiated_by => 'admin',
                start_time   => 1704067200
            },
            {
                job_uuid     => 'restore-2',
                restore_type => 'custom',
                users        => ['user2'],
                status       => 'running',
                initiated_by => 'root',
                start_time   => 1704153600
            }
        );
    } );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( {} ) };

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    is( $metadata->{result}, 1, 'Metadata result is ok' );
    is( scalar @{ $result->{history} }, 2, 'Two restore entries returned' );
    is( $result->{total_entries}, 2, 'total_entries is 2' );
    is( $result->{history}[0]{status}, 'completed', 'First entry status is correct' );
    is( $result->{history}[1]{status}, 'running', 'Second entry status is correct' );
};

subtest 'list_restore_history - database error handling' => sub {
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_history' => sub {
        die "Database connection failed";
    } );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( {} ) };

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    is( $metadata->{result}, 0, 'Metadata result is not ok on error' );
    is( scalar @{ $result->{history} }, 0, 'History is empty on error' );
    is( $result->{total_entries}, 0, 'total_entries is 0 on error' );
};

subtest 'list_restore_history - filters_applied tracking' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        status       => 'completed',
        initiated_by => 'admin',
        limit        => 100
    } ) };

    my $result = Whostmgr::API::1::CometBackup::list_restore_history( $args, $metadata );

    ok( exists $result->{filters_applied}{status}, 'status in filters_applied' );
    ok( exists $result->{filters_applied}{initiated_by}, 'initiated_by in filters_applied' );
    is( $result->{filters_applied}{status}, 'completed', 'status filter value correct' );
    is( $result->{filters_applied}{initiated_by}, 'admin', 'initiated_by filter value correct' );
};

done_testing();
