#!/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 {}; }
    sub _get_user_connection_id { return 'conn-123'; }

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

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

    $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{'Data/UUID.pm'} = 1;
    package Data::UUID;
    sub new { return bless {}, shift; }
    sub create_str { return '550e8400-e29b-41d4-a716-446655440000'; }

    $INC{'Cpanel/Daemonizer/Tiny.pm'} = 1;
    package Cpanel::Daemonizer::Tiny;
    sub run_as_daemon { 
        my ($code) = @_;
        $code->() if ref $code eq 'CODE';
        return 12345;
    }
}

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

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

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

subtest 'run_restore_job - missing type parameter' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { users => ['user1'] } ) };

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    is( $result->{job}, {}, 'Job is empty hash' );
};

subtest 'run_restore_job - invalid type parameter' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        type  => 'invalid',
        users => ['user1']
    } ) };

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    is( $result->{job}, {}, 'Job is empty hash' );
};

subtest 'run_restore_job - missing users parameter' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { type => 'full' } ) };

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    is( $result->{job}, {}, 'Job is empty hash' );
};

subtest 'run_restore_job - empty users array' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        type  => 'full',
        users => []
    } ) };

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    is( $result->{job}, {}, 'Job is empty hash' );
};

subtest 'run_restore_job - full restore success' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        type  => 'full',
        users => ['user1', 'user2']
    } ) };

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

    is( $metadata->{result}, 1, 'Metadata result is ok' );
    ok( defined $result->{job}{job_uuid}, 'Job UUID is defined' );
    is( $result->{job}{restore_type}, 'full', 'Restore type is full' );
    is( $result->{job}{status}, 'running', 'Status is running' );
    is( scalar @{ $result->{job}{users} }, 2, 'Users array has 2 items' );
};

subtest 'run_restore_job - custom restore missing snapshot_id' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        type  => 'custom',
        users => ['user1'],
        source_id => 'src-123',
        destination_id => 'dst-456'
    } ) };

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    is( $result->{job}, {}, 'Job is empty hash' );
};

subtest 'run_restore_job - custom restore missing source_id' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        type  => 'custom',
        users => ['user1'],
        snapshot_id => 'snap-123',
        destination_id => 'dst-456'
    } ) };

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    is( $result->{job}, {}, 'Job is empty hash' );
};

subtest 'run_restore_job - custom restore missing destination_id' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        type  => 'custom',
        users => ['user1'],
        snapshot_id => 'snap-123',
        source_id => 'src-123'
    } ) };

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    is( $result->{job}, {}, 'Job is empty hash' );
};

subtest 'run_restore_job - custom restore multiple users not allowed' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        type  => 'custom',
        users => ['user1', 'user2'],
        snapshot_id => 'snap-123',
        source_id => 'src-123',
        destination_id => 'dst-456'
    } ) };

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

    is( $metadata->{result}, 0, 'Metadata result is not ok' );
    is( $result->{job}, {}, 'Job is empty hash' );
};

subtest 'run_restore_job - response structure' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        type  => 'full',
        users => ['user1']
    } ) };

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

    ok( exists $result->{job}, 'Response has job key' );
    ok( exists $result->{job}{job_uuid}, 'Job has job_uuid' );
    ok( exists $result->{job}{restore_type}, 'Job has restore_type' );
    ok( exists $result->{job}{users}, 'Job has users' );
    ok( exists $result->{job}{status}, 'Job has status' );
    ok( exists $result->{job}{initiated_by}, 'Job has initiated_by' );
};

subtest 'run_restore_job - initiated_by defaults to root' => sub {
    my $metadata = {};
    my $args     = { json => Cpanel::JSON::Dump( { 
        type  => 'full',
        users => ['user1']
    } ) };

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

    is( $result->{job}{initiated_by}, 'root', 'Initiated_by defaults to root' );
};

done_testing();
