#!/usr/local/cpanel/3rdparty/bin/perl
# cpanel - whmcs_install                             Copyright 2018 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
package scripts::whmcs_install;

use strict;
use warnings;

use lib "/usr/local/cpanel/cpaddons/";

use Cwd                                ();
use cPanel::Automation::WHMCS::BestPHP ();    # provided by this cpaddon
use Cpanel::SafeRun::Object            ();
use Cpanel::DomainLookup::DocRoot      ();
use Getopt::Long                       ();
use Pod::Usage                         ();

=head1 DESCRIPTION

This script runs the php install script that comes with whmcs. You must pass an install directory parameter.

=head1 USAGE

whmcs_install --dir={install directory} --domain={install domain}

Where:

=over

=item * --dir={string} - The install directory for whmcs on the file system.

=item * --domain={string} - The docroot for the installation (may be higher
up than the actual WHMCS installation). This is needed to find the correct
php.ini file to use.

=back

=cut

exit( __PACKAGE__->run(@ARGV) ) if !caller;

=head1 FUNCTIONS

=head2 run(dir => {String}, domain => {String})

Modulino for the whmcs_install program.

=head3 ARGUMENTS

HASH with the following structure:

=over

=item dir

String - The location where whmcs php files are located for the specific install. Required.

=back

=head3 RETURNS

1 if successful

=head3 THROWS

=over

=item * When you do not pass in the required arguments.

=item * When the installer.php script is missing or unreadable.

=item * When the php runtime can not be run the user.

=item * When the installer.php script fails in certain ways.

=back

=cut

sub run {
    my ( $self, @args ) = @_;
    my ( $help, $man, $dir, $domain, $verbose, $debug ) = ( 0, 0, '', '', 0, 0 );

    Getopt::Long::Configure("pass_through");
    Getopt::Long::GetOptionsFromArray(
        \@args,
        'help|?'    => \$help,
        'man'       => \$man,
        'dir=s'     => \$dir,
        'domain=s'  => \$domain,
        'verbose|v' => \$verbose,
        'debug'     => \$debug,
    ) or Pod::Usage::pod2usage(2);
    Pod::Usage::pod2usage(1) if $help;
    Pod::Usage::pod2usage( -exitval => 0, -verbose => 2 ) if $man;

    if ( !$dir ) {
        die 'You must pass the install directory parameter: --dir';
    }

    # Save the old directory so we can get back to where we were.
    my $cwd        = Cwd::getcwd();
    my $PHP_SCRIPT = 'install/bin/installer.php';

    # We need to be in the install directory to
    # get the correct php version from /usr/bin/php
    # helper.
    chdir $dir or die "chdir: $dir: $!";

    if ($verbose) {
        print "Starting WHMCS installer\n";
    }

    my $best_php = cPanel::Automation::WHMCS::BestPHP::get_best_php( verbose => $verbose );
    if ( !$best_php || !length($best_php) ) {
        die "Could not find a version of php installed that has all the required extensions installed.";
    }

    # The best PHP value has a format like ea-phpXX (same as the symlinks)
    my $php_bin_path = '/usr/local/bin/' . $best_php;
    if ( !-x $php_bin_path ) {
        require Cpanel::PHPConfig::CLI;
        $php_bin_path = Cpanel::PHPConfig::CLI::get_php_cli();

        warn "The PHP symlink for $best_php could not be found. Using $php_bin_path instead.";
    }

    # Locate the correct php.ini file to use. This is needed to ensure we get a high enough
    # memory limit for the installer to finish.
    my $all_docroots = Cpanel::DomainLookup::DocRoot::getdocroots();
    my $docroot      = $all_docroots->{$domain} || die "Couldn't find docroot for “$domain”.";
    my $ini          = "$docroot/php.ini";

    my @php_args = (
        '-c',
        $ini,
        '-f',
        "$dir/$PHP_SCRIPT",
        '--',
        '-i',
        '-n',
    );

    if ($debug) {
        print "Actual Command: $php_bin_path @php_args\n";
    }

    my $run = Cpanel::SafeRun::Object->new(
        program     => $php_bin_path,
        args        => \@php_args,
        before_exec => sub {
            $ENV{TERM} = 'xterm';
        }
    );

    # Restore to the original directory
    chdir $cwd or die "chdir: $cwd: $!";

    if ( $run->CHILD_ERROR() ) {
        die "Failed to run install script $dir/$PHP_SCRIPT with the following error: " . $run->stdout() . " " . $run->stderr();
    }
    if ( my $error = $run->stderr() ) {
        die "The install script $dir/$PHP_SCRIPT failed with the following error: $error";
    }

    if ($verbose) {
        print $run->stdout();
        print "WHMCS installer succeeded\n";
    }

    return 0;
}

1;
