#!/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 plugin::retry_domain_migration;

use cPstrict;

=encoding utf-8

=head1 NAME

retry_domain_migration

=head1 USAGE

retry_domain_migration.pl [--username <username> --old_domain <old domain> --new_domain <new domain> | --config <path to config> | --help]

If config is provided, it will override the command line parameters, otherwise you must provide the username, old_domain, and new_domain parameters.

=head1 DESCRIPTION

This script can be called to retry or finish moving a sitejet website in the case that it failed earlier.

=over

=item username - string

The cPanel username of the Sitejet website owner.

=item old_domain - string

The previous domain.

=item new_domain - string

The domain to finish migrating to.

=item config - string

The path to a YAML configuration file that contains the keys: username, old_domain, new_domain.

=item help

Show the help for this script.

=item verbose

Show more verbose output.

=back

=cut

use Cpanel::AccessIds;
use Cpanel::Imports;
use Cpanel::PwCache;
use Cpanel::Sitejet::MoveWebsite;

use Common::YAML ();

use parent qw( Cpanel::HelpfulScript );

use constant _OPTIONS => (
    'username=s',
    'old_domain=s',
    'new_domain=s',
    'config=s',
    'verbose!',
);

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

=head2 I<OBJ>->run()

Runs this script.

=cut

sub run ($self) {
    my $user        = $self->getopt('username');
    my $old_domain  = $self->getopt('old_domain');
    my $new_domain  = $self->getopt('new_domain');
    my $config_path = $self->getopt('config');
    my $config;

    if ($config_path) {
        $config     = _load_config($config_path);
        $user       = $config->{'username'};
        $old_domain = $config->{'old_domain'};
        $new_domain = $config->{'new_domain'};
    }

    if ( !$user || !$old_domain || !$new_domain ) {
        die $self->full_help();
    }

    # this needs to be set as Sitejet Connector expects
    # these variables to be defined.
    local $Cpanel::user    = $user;
    local $Cpanel::homedir = Cpanel::PwCache::gethomedir($user);

    my $result;
    eval {
        $result = Cpanel::AccessIds::do_as_user_with_exception(
            $user,
            sub {
                # File::Find::Rule throws exception if we do not run from user dir
                # die early if unable to change directory
                chdir($Cpanel::homedir) or die "Could not change dir to $Cpanel::homedir due to: '$!'";
                my $move_website_obj = Cpanel::Sitejet::MoveWebsite->new( $old_domain, $new_domain );
                return $move_website_obj->run();
            }
        );
    };

    if ( $result && $result < 0 ) {
        my $msg = sprintf( "Cannot migrate Sitejet website from %s to %s: you have either not created a Sitejet website on the temporary domain, or the registered domain already has one.", $old_domain, $new_domain );
        logger->info($msg);

        # this is not a failure technically, so lets send a positive result
        return 1;

    }

    my $exception;
    if ( ( $exception = $@ ) || !$result ) {
        logger()->error("Failed to migrate your Sitejet website(s): '$exception'. Run the following command to retry: '/var/cpanel/plugins/sitejet/scripts/retry_domain_migration.pl --username $user --old_domain $old_domain --new_domain $new_domain'");

        # overwrite the memento file with new exception
        # ensure it is written as user
        Cpanel::AccessIds::do_as_user_with_exception(
            $user,
            sub {
                require Cpanel::Sitejet::Hooks::ChangeDomains;
                Cpanel::Sitejet::Hooks::ChangeDomains::_create_failure_memento( $user, $old_domain, $new_domain, $exception );
            }
        );

        return 0;
    }
    logger()->info("Moved website data successfully.");

    return 1;
}

sub _load_config ($config_path) {
    if ( !$config_path ) {
        die "Please provide a config file path.";
    }

    my $config_file = Common::YAML::load($config_path);

    if ( ref $config_file ne 'HASH' ) {
        die "Invalid config file format. Expected a YAML file with a hash structure.";
    }

    return $config_file;
}

1;
