#!/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 '/tmp/restore_' . $_[0] . '.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_job { return undef; }
}

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 'get_restore_log - missing JSON parameter' => sub {
    my $metadata = {};
    my $args     = {};

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    ok( !defined $result, 'Result is undef' );
};

subtest 'get_restore_log - missing job_uuid' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( {} ) };

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    is( $result->{log}, '', 'Log is empty' );
};

subtest 'get_restore_log - job not found' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { job_uuid => 'nonexistent' } ) };

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    is( $result->{log}, '', 'Log is empty' );
};

subtest 'get_restore_log - with n_line offset' => sub {
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_job' => sub {
        return { status => 'completed' };
    } );

    my $log_content = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n";
    my $mock_file = Test::MockFile->file( '/tmp/restore_job-456.log', $log_content );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        job_uuid => 'job-456',
        n_line   => 2
    } ) };

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

    is( $metadata->{result}, 1, 'Metadata result is ok' );
    like( $result->{log}, qr/Line 3/, 'Log contains line 3' );
    is( $result->{start_line}, 2, 'start_line is 2' );
};

subtest 'get_restore_log - response structure' => sub {
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_job' => sub {
        return { status => 'completed' };
    } );

    my $log_content = "Test log content\n";
    my $mock_file = Test::MockFile->file( '/tmp/restore_job-789.log', $log_content );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { job_uuid => 'job-789' } ) };

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

    ok( exists $result->{log}, 'Response has log key' );
    ok( exists $result->{job_uuid}, 'Response has job_uuid' );
    ok( exists $result->{status}, 'Response has status' );
    ok( exists $result->{result}, 'Response has result' );
    ok( exists $result->{start_line}, 'Response has start_line' );
    ok( exists $result->{end_line}, 'Response has end_line' );
    ok( exists $result->{total_lines}, 'Response has total_lines' );
};

subtest 'get_restore_log - default n_line is 0' => sub {
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_job' => sub {
        return { status => 'completed' };
    } );

    my $log_content = "Line 1\nLine 2\nLine 3\n";
    my $mock_file = Test::MockFile->file( '/tmp/restore_job-default.log', $log_content );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { job_uuid => 'job-default' } ) };

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

    is( $result->{start_line}, 0, 'start_line defaults to 0' );
    like( $result->{log}, qr/Line 1/, 'Log contains line 1' );
};

subtest 'get_restore_log - n_line beyond file length' => sub {
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_job' => sub {
        return { status => 'completed' };
    } );

    my $log_content = "Line 1\nLine 2\n";
    my $mock_file = Test::MockFile->file( '/tmp/restore_job-beyond.log', $log_content );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        job_uuid => 'job-beyond',
        n_line   => 100
    } ) };

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

    is( $result->{log}, '', 'Log is empty when n_line is beyond file' );
};

subtest 'get_restore_log - job_result extraction success' => sub {
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_job' => sub {
        return { status => 'completed' };
    } );

    my $log_content = "Restore started\nJob completed (SUCCESS)\nRestore finished\n";
    my $mock_file = Test::MockFile->file( '/tmp/restore_job-success.log', $log_content );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { job_uuid => 'job-success' } ) };

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

    is( $result->{result}, 'success', 'Result extracted as success' );
};

subtest 'get_restore_log - job_result extraction failed' => sub {
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_job' => sub {
        return { status => 'failed' };
    } );

    my $log_content = "Restore started\nJob completed (FAILED)\nError occurred\n";
    my $mock_file = Test::MockFile->file( '/tmp/restore_job-failed.log', $log_content );

    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { job_uuid => 'job-failed' } ) };

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

    is( $result->{result}, 'failed', 'Result extracted as failed' );
};

subtest 'get_restore_log - job status values' => sub {
    my $mock_logs = Test::MockModule->new('Whostmgr::CometBackup::RestoreRunLogs');
    $mock_logs->redefine( 'get_restore_job' => sub {
        my ($self, $job_uuid) = @_;
        if ($job_uuid eq 'running') {
            return { status => 'running' };
        } elsif ($job_uuid eq 'completed') {
            return { status => 'completed' };
        }
        return { status => 'unknown' };
    } );

    my $log_content = "Test\n";
    my $mock_file1 = Test::MockFile->file( '/tmp/restore_running.log', $log_content );
    my $mock_file2 = Test::MockFile->file( '/tmp/restore_completed.log', $log_content );

    my $metadata1 = {};
    my $args1 = { json => Cpanel::JSON::Dump( { job_uuid => 'running' } ) };
    my $result1 = Whostmgr::API::1::CometBackup::get_restore_log( $args1, $metadata1 );
    is( $result1->{status}, 'running', 'Status is running' );

    my $metadata2 = {};
    my $args2 = { json => Cpanel::JSON::Dump( { job_uuid => 'completed' } ) };
    my $result2 = Whostmgr::API::1::CometBackup::get_restore_log( $args2, $metadata2 );
    is( $result2->{status}, 'completed', 'Status is completed' );
};

done_testing();
