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

package Cpanel::Admin::Modules::Cpanel::xovi;

use cPstrict;

use Cpanel::Exception              ();
use Cpanel::JSON                   ();
use Cpanel::License::CompanyID     ();
use Cpanel::Plugins::RestApiClient ();
use Cpanel::Plugins::ServerId      ();

use parent qw( Cpanel::Admin::Base );

use constant {
    SECRETS_FILE => '/var/cpanel/plugins/xovi/.config/secrets',
    DEBUG        => 0
};

=encoding utf-8

=head1 NAME

Cpanel::Admin::Modules::Cpanel::xovi

=head1 SYNOPSIS

  use Cpanel::AdminBin::Call ();

  Cpanel::AdminBin::Call::call ( "Cpanel", "xovi", "CREATE_USER", {} );

=head1 DESCRIPTION

This admin bin is used to read root owned api tokens as the adminbin user.

=cut

sub _actions {
    return qw(CREATE_USER);
}

use constant _allowed_parents => (
    __PACKAGE__->SUPER::_allowed_parents(),
);

my $API_HOST = 'https://api.xovi.net/';

=head1 METHODS

=head2 CREATE_USER()

Calls xovi API to create a XOVI account and returns API-KEY

=head2 RETURNS

API-KEY on success
Dies on failure.

=cut

sub CREATE_USER {
    my $self             = shift;
    my $endpoint         = ".third-party-users";
    my $third_party_data = $self->_generate_third_party_data();

    my $auth_data = {
        'data-type' => "Xovi\\API\\Auth\\SecurityConstraints",
        'data'      => {
            'auth-method'      => { 'data-type' => "Xovi\\API\\Auth\\Method\\XoviApikey" },
            'third-party-data' => $third_party_data
        },
        'meta' => {
            'verification' => {
                'data-type' => "Xovi\\API\\Data\\Meta\\Verification\\CpanelExtension",
            }
        }
    };

    my $headers = _add_api_token_header();
    my $api     = Cpanel::Plugins::RestApiClient->new();

    my %request = (
        method   => 'PUT',
        base_url => $API_HOST,
        headers  => $headers,
        endpoint => $endpoint,
        payload  => $auth_data
    );

    while ( my ($setter, $value) = each %request ) {
        $api->$setter($value);
    }

    if (DEBUG) {
        require Data::Dumper;
        local $Data::Dumper::Terse = 1;
        my $dump = Data::Dumper::Dumper(\%request);
        *STDERR->write("\nCREATE_USER [request]\t$dump");
    }

    my $response = Cpanel::JSON::Load($api->run);

    if (DEBUG) {
        require Data::Dumper;
        local $Data::Dumper::Terse = 1;
        my $dump = Data::Dumper::Dumper($response);
        *STDERR->write("\nCREATE_USER [response]\t$dump");
    }

    return $response->{data}->{'apikey'};

}

=head1 METHODS

=head2 _add_api_token_header()

Fetch the Auth Tokens needed for xovi account creation and
appends the token to the header object

=head2 RETURNS

A hash ref containing key value mapping on success.
Ex:
    $header = {
               'Content-Type' => "application/json",
               'Xoviapi-Key' => '121ghgjgjkh',
               'Xoviapi-Password' => '12ghghgjh12',
               'user-agent' => 'libwww-perl/6.67'
     };

Dies on failure.

=cut

sub _add_api_token_header {

    my $token_data = {};
    if ( open my $fh, '<', SECRETS_FILE ) {
        my $data;
        while ( $data = <$fh> ) {
            chomp($data);
            my ( $key, $value ) = ( split /:/, $data );
            if ( $key && $key eq 'username' ) {
                $token_data->{'Xoviapi-Key'} = $value;
            }
            if ( $key && $key eq 'credential' ) {
                $token_data->{'Xoviapi-Password'} = $value;
            }
        }
    }
    else {
        die Cpanel::Exception::create( 'IO::FileOpenError', 'The system could not read the tokens file.' );
    }
    $token_data->{'Content-Type'} = 'application/json';
    $token_data->{'user-agent'}   = 'libwww-perl/6.67';
    return $token_data;
}

sub _generate_third_party_data ($self) {
    my $data_type = "Xovi\\API\\Data\\Types\\User\\ThirdPartyData";
    my $data      = [];

    _add_data( $data, 'company_id',     Cpanel::License::CompanyID::get_company_id() );
    _add_data( $data, 'panel_username', $self->get_caller_username() );
    _add_data( $data, 'server_id',      Cpanel::Plugins::ServerId::get_server_id() );

    return $data;
}

sub _add_data ( $data, $label, $value ) {
    my $data_type = "Xovi\\API\\Data\\Types\\User\\ThirdPartyData";
    push @$data, {
        'data-type' => $data_type,
        'data'      => {
            'label' => $label,
            'value' => $value
        }
    };
}

1;
