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

# cpanel - t/medium/Cpanel-Admin-Modules-Cpanel-sitejet.t
#                                                  Copyright 2023 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

package t::medium::Cpanel::Admin::Modules::Team::sitejet;

use Test2::V0 -no_utf8 => 1;
use Test2::Tools::Explain;
use Test2::Plugin::NoWarnings;
use Test2::Tools::Exception qw/dies/;

use Test::MockObject;
use Test::MockFile;
use Test::MockTime;
use Test::Warn;

use Try::Tiny;

use Test::Cpanel::Policy;

use parent qw(
  Cpanel::TestObj
);

use Cpanel::Admin::Modules::Cpanel::sitejet ();

__PACKAGE__->new()->runtests() if !caller;

#----------------------------------------------------------------------

#e.g., num_method_tests()
sub new ( $class, @args ) {
    my $self = $class->SUPER::new(@args);
    return $self;
}

#e.g., set environs before running tests
sub runtests ( $self, @args ) {
    $self->{'mock_cpuser_file_DNE'} = Test::MockFile->file('/var/cpanel/users/team_user_name');
    return $self->SUPER::runtests(@args);
}

sub test__actions : Tests(1) ($self) {

    my @got = Cpanel::Admin::Modules::Cpanel::sitejet->_actions();
    ok( scalar @got >= 1, '_actions returns an array with at least 1 item', explain @got );

    return;
}

sub test_ADD_API_TOKEN : Tests(9) ($self) {
    my $api_token = 'abc45678901234567890123456789012';
    my $conf      = bless(
        {
            user => 'team_user_name',
            data => {},
        },
        'Cpanel::Config::CpUserGuard'
    );
    my @mocks = (
        $self->mock_subs(
            'Cpanel::Admin::Base::get_caller_username' => 'team_user_name',
            'Cpanel::Config::CpUserGuard::new'         => sub {
                return $conf;
            },
            'Cpanel::Config::CpUserGuard::save' => sub {
                return 1;
            },
        )
    );
    my $got = Cpanel::Admin::Modules::Cpanel::sitejet->ADD_API_TOKEN($api_token);

    ok( $got, 'ADD_API_KEY runs without errors', explain $got);
    is( $conf->{'data'}->{'SITEJET_API_TOKEN'}, $api_token, 'ADD_API_KEY puts key into cpuser data' ) or diag explain $conf;

    my @bad_tokens = ( 'abc4567890123456789012345678901', '', '0', '-1', 'Abc45678901234567890123456789012', '&bc45678901234567890123456789012', "abc45678901234567890123456789012\n" );
    for my $bad_token (@bad_tokens) {
        like(
            dies {
                $got = Cpanel::Admin::Modules::Cpanel::sitejet->ADD_API_TOKEN($bad_token);
            },
            qr/Invalid token/,
            "ADD_API_KEY dies as expected with input $bad_token."
        );
    }

    return;
}

sub test_DISK_QUOTA_CHECK : Tests(3) ($self) {
    my $mocks         = _get_mocks();
    my $domain        = $mocks->{'domain'};
    my $document_root = $mocks->{'document_root'};
    my @mocks         = (
        $self->mock_subs(
            'Cpanel::Admin::Base::get_caller_username'            => $mocks->{'user'},
            'Cpanel::Admin::Base::get_cpuser_homedir'             => $mocks->{'homedir'},
            'Cpanel::WebDisk::api2_listwebdisks'                  => ( $mocks->{'webdisk'} ),
            'Cpanel::Admin::Base::verify_that_cpuser_owns_domain' => 1,
            'Cpanel::SysQuota::analyzerepquotadata'               => sub {
                return (
                    { 'tommy' => '1000' },
                    { 'tommy' => '10000' }
                );
            },
            'Cpanel::SafeRun::Errors::saferunallerrors' => sub {
                return "100 $document_root";
            },
            'Cpanel::DomainLookup::DocRoot::getdocroots' => { 'tommy.tld' => $document_root },
        )
    );
    my $got = Cpanel::Admin::Modules::Cpanel::sitejet->DISK_QUOTA_CHECK($domain);

    my $expected_output = {
        'tommy.tld' => {

            'can_backup'       => 1,
            'available_space'  => int( 9000 / 1024 ),
            'required_space'   => int( 100 / 1024 ),
            'is_docroot_empty' => 1
        }
    };

    is( $got, $expected_output, 'test_DISK_QUOTA_CHECK returns data status as expected.' ) or diag explain $got;

    $got = Cpanel::Admin::Modules::Cpanel::sitejet->DISK_QUOTA_CHECK();
    is( $got, $expected_output, 'test_DISK_QUOTA_CHECK returns data status as expected when no domain is passed as an argument.' ) or diag explain $got;

    @mocks = ();
    @mocks = (
        $self->mock_subs(
            'Cpanel::Admin::Base::get_caller_username'            => 'tommy',
            'Cpanel::Admin::Base::get_cpuser_homedir'             => $mocks->{'homedir'},
            'Cpanel::WebDisk::api2_listwebdisks'                  => ( $mocks->{'webdisk'} ),
            'Cpanel::Admin::Base::verify_that_cpuser_owns_domain' => 1,
            'Cpanel::SysQuota::analyzerepquotadata'               => sub {
                return (
                    { 'tommy' => '1000' },
                    { 'tommy' => '10000' }
                );
            },
            'Cpanel::SafeRun::Errors::saferunallerrors' => sub {
                return "99000 $document_root";
            },
            'Cpanel::DomainLookup::DocRoot::getdocroots' => { 'tommy.tld' => $document_root },
        )
    );

    # create a non-empty file in doc_root
    $mocks->{'non_empty_file'} = Test::MockFile->file( "$document_root/non_empty", 'non empty' );
    $got = Cpanel::Admin::Modules::Cpanel::sitejet->DISK_QUOTA_CHECK($domain);

    $expected_output = {
        'tommy.tld' => {
            'can_backup'       => 0,
            'available_space'  => int( 9000 / 1024 ),
            'required_space'   => int( 99000 / 1024 ),
            'is_docroot_empty' => 0
        }
    };

    is( $got, $expected_output, 'test_DISK_QUOTA_CHECK returns exact data status as expected with non-empty document_root.' ) or diag explain $got;

    return;
}

sub _get_mocks {
    my %mocks = ();
    $mocks{'user'}          = 'tommy';
    $mocks{'domain'}        = 'tommy.tld';
    $mocks{'homedir'}       = '/home/tommy';
    $mocks{'document_root'} = '/home/tommy/public_html';
    $mocks{'webdisk'}       = "$mocks{'document_root'}/webdisk";
    $mocks{'dir_mock'}      = Test::MockFile->new_dir( $mocks{'document_root'} );
    $mocks{'well_known'}    = Test::MockFile->new_dir("$mocks{'document_root'}/.well-known");
    $mocks{'htaccess'}      = Test::MockFile->file( "$mocks{'document_root'}/.htaccess", '' );
    $mocks{'webdisk_mock'}  = Test::MockFile->file( $mocks{'webdisk'},                   '' );
    return \%mocks;
}
