0x10000000
  #   Oˆl–Ãa¾”êeJq@ŠãNÜdJbÑ¿Ø„ià¼çÂÕ ?÷     O#!/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 MigrScr;

# Conversion script from CCS data to CPDAVD

use strict;
no strict 'refs';    # XXX WHY
use warnings;
use DBD::Pg;
use Digest::MD5;
use MIME::Base64;

use Data::Dumper;

use Cpanel::JSON                 ();
use Cpanel::AcctUtils::Lookup    ();
use Cpanel::PwCache              ();
use Cpanel::SafeDir::MK          ();
use Cpanel::DAV::CaldavCarddav   ();
use Cpanel::FileUtils::TouchFile ();
use Cpanel::DAV::Defaults        ();
use Cpanel::DAV::Calendars       ();
use Cpanel::DAV::Tasks           ();
use Cpanel::DAV::AddressBooks    ();

use parent 'Cpanel::HelpfulScript';

sub _OPTIONS {
    return qw(
      help
      overwrite
      dryrun
      verbosity=s
      user=s
    );
}

if ( $> != 0 ) {
    die "This script must be run by the root user\n";
}

#################################################################################################################################
# Set defaults
#################################################################################################################################

my $overwrite_existing = 0;
my $verbosity          = 1;
my $dryrun             = 0;
my $singleuser;

# ++'d every time there is a logmsg with -1 prio
my $errcnt = 0;

# Save any user that has run into an error while writing ( likely an account being over quota ) and will help cut down on futile attempts
my %user_has_write_errors;

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

sub run {    ## no critic(Subroutines::ProhibitExcessComplexity)
    my ($self) = @_;
    #################################################################################################################################
    # Get arguments to override the defaults
    #################################################################################################################################

    if ( $self->getopt('overwrite') ) {
        logmsg( 1, "Overwriting existing entry files" );
        $overwrite_existing = 1;
    }
    if ( $self->getopt('dryrun') ) {
        logmsg( 1, "Dry run, no changes will be made anywhere" );
        $dryrun = 1;
    }
    if ( defined( $verbosity = $self->getopt('verbosity') ) ) {
        logmsg( 1, "Setting verbosity to $verbosity" );
    }
    if ( defined( $singleuser = $self->getopt('user') ) ) {
        logmsg( 1, "Only processing the single account: $singleuser" );
    }

    # Map data to a local system and mail user by UIDs
    if ( !-f '/var/cpanel/ccs/ccs-persistance.json' ) {
        logmsg( -1, "This server does not appear to have the file /var/cpanel/ccs/ccs-persistance.json , which is critical for converting from CCS to native CPDAVD." );
        return 1;
    }

    logmsg( 1, "Starting migration from CCS to native CPDAVD" );

    my $pers_data_hr           = Cpanel::JSON::SafeLoadFile('/var/cpanel/ccs/ccs-persistance.json');
    my %pers_data_keyed_on_uid = reverse %{ $pers_data_hr->{'users'} };

    # print "\npers_data_hr:\n" . Dumper( $pers_data_hr );
    # print "\npers_data_keyed_on_uid:\n" . Dumper( \%pers_data_keyed_on_uid );

    #################################################################################################################################
    # Create a hash that contains all the important known information about the accounts, keyed on CCS UID
    #################################################################################################################################

    # This hash is our main mapping for account (email or system), the system user that owns the account, and the home directory for the system user.
    # These are used quite often so it makes sense to build this once.
    my %user_l