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

#                                      Copyright 2026 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 scripts::panel_ini;

=head1 NAME

scripts::panel_ini

=head1 USAGE

    panel_ini set    <key> <value>
    panel_ini delete <key>
    panel_ini get    <key>
    panel_ini --help

=head1 DESCRIPTION

Command-line interface for managing panel.ini overrides. This script
allows administrators to safely add, update, and remove configuration
entries without manually editing the INI file.

Keys must use dot notation with at least one dot separating the section
name from the key name (e.g., C<whm.feature.foo>).

=head1 COMMANDS

=over

=item set <key> <value>

Add or update a key in panel.ini.

=item delete <key>

Remove a key from panel.ini.

=item get <key>

Display the current effective value for a key.

=back

=head1 KEY FORMAT

Keys use dot notation. The leftmost part is the INI section name
and the rest is the key within that section.

Examples:

    whm.feature.foo
    ext-wp-toolkit.kishkaEnabled
    navigation.newHomeView.enabled

=cut

use cPstrict;

use parent qw( Cpanel::HelpfulScript );

use Cpanel::JSON  ();
use Cpanel::Leika ();

use constant _ACCEPT_UNNAMED => 1;
use constant _OPTIONS        => ();

exit( __PACKAGE__->new(@ARGV)->script() // 0 ) unless caller;

=head2 script()

Main entry point. Parses arguments, dispatches to the appropriate
subcommand handler, and returns an exit code.

=cut

sub script ($self) {
    my @unnamed    = $self->getopt_unnamed();
    my $subcommand = shift @unnamed;

    die $self->help("No command specified.\n") unless $subcommand;

    if ( $subcommand eq 'set' ) {
        return $self->cmd_set(@unnamed);
    }
    elsif ( $subcommand eq 'delete' ) {
        return $self->cmd_delete(@unnamed);
    }
    elsif ( $subcommand eq 'get' ) {
        return $self->cmd_get(@unnamed);
    }
    else {
        die $self->help("Unknown command: $subcommand\n");
    }
}

=head2 cmd_set(@args)

Handles the C<set> subcommand. Expects exactly two arguments: a key
and a value. Sets the key in panel.ini via C<Cpanel::Leika>.

Returns 0 on success; dies on usage error or write failure.

=cut

sub cmd_set ( $self, @args ) {
    if ( @args != 2 ) {
        die $self->help("The 'set' command requires exactly two arguments: <key> <value>\n");
    }

    my ( $key, $value ) = @args;

    $self->ensure_root();

    eval { Cpanel::Leika::set_leika_override( $key, $value ) };
    if ($@) {
        my $err = $@;
        chomp $err;
        die "Failed to set '$key': $err\n";
    }

    say "Set '$key' to '$value' in panel.ini.";
    return 0;
}

=head2 cmd_delete(@args)

Handles the C<delete> subcommand. Expects exactly one argument: a key.
Removes the key from panel.ini via C<Cpanel::Leika>.

Returns 0 on success; dies on usage error or write failure.

=cut

sub cmd_delete ( $self, @args ) {
    if ( @args != 1 ) {
        die $self->help("The 'delete' command requires exactly one argument: <key>\n");
    }

    my ($key) = @args;

    $self->ensure_root();

    eval { Cpanel::Leika::delete_leika_override($key) };
    if ($@) {
        my $err = $@;
        chomp $err;
        die "Failed to delete '$key': $err\n";
    }

    say "Deleted '$key' from panel.ini.";
    return 0;
}

=head2 cmd_get(@args)

Handles the C<get> subcommand. Expects exactly one argument: a key.
Displays the current effective value (leika.conf merged with panel.ini
overrides) for the key.

Returns 0 on success; dies on usage error.

=cut

sub cmd_get ( $self, @args ) {
    if ( @args != 1 ) {
        die $self->help("The 'get' command requires exactly one argument: <key>\n");
    }

    my ($key) = @args;

    my $value = Cpanel::Leika::get_config($key);

    if ( !defined $value ) {
        say "'$key' is not set or has a null value.";
    }
    elsif ( ref $value ) {
        say Cpanel::JSON::pretty_dump($value);
    }
    else {
        say $value;
    }

    return 0;
}

1;
