<?php

use XcVm\Cli\Commands\MigrateCommand;
use XcVm\Core\Auth\AuthRepository;
use XcVm\Core\Database\Database;
use XcVm\Core\Database\DatabaseHandler;
use XcVm\Core\Database\QueryHelper;

/**
 * Database migration logic
 *
 * @package XC_VM_CLI
 * @author  Divarion_D <https://github.com/Divarion-D>
 * @copyright 2025-2026 Vateron Media
 * @link    https://github.com/Vateron-Media/XC_VM
 * @license AGPL-3.0 https://www.gnu.org/licenses/agpl-3.0.html
 */

// Migration logic — loaded from MigrateCommand
// Requires admin.php already loaded, $db available
set_time_limit(0);
ini_set('memory_limit', -1);
global $db;
$rXUITableList = array('access_codes', 'users', 'blocked_ips', 'blocked_uas', 'blocked_isps', 'bouquets', 'enigma2_devices', 'mag_devices', 'epg', 'users_groups', 'users_packages', 'rtmp_ips', 'streams_series', 'streams_episodes', 'servers', 'streams', 'streams_options', 'streams_servers', 'streams_categories', 'tickets', 'tickets_replies', 'profiles', 'lines', 'watch_folders');
$rTableList = array('reg_users', 'users', 'enigma2_devices', 'mag_devices', 'user_output', 'streaming_servers', 'series', 'series_episodes', 'streams', 'streams_sys', 'streams_options', 'stream_categories', 'bouquets', 'member_groups', 'packages', 'rtmp_ips', 'epg', 'blocked_ips', 'blocked_user_agents', 'isp_addon', 'tickets', 'tickets_replies', 'transcoding_profiles', 'watch_folders', 'categories', 'epg_sources', 'members', 'blocked_isps', 'groups', 'servers', 'stream_servers');
$rMigrateOptions = (json_decode(file_get_contents(TMP_PATH . '.migration.options'), true) ?: array());

file_put_contents(TMP_PATH . '.migration.pid', getmypid());
file_put_contents(TMP_PATH . '.migration.status', 1);
$odb = new DatabaseHandler(migrate: true);
if (!$odb->connected) {
    echo 'Failed to connect to migration database, or database is empty!' . "\n";
    file_put_contents(TMP_PATH . '.migration.status', 3);
    exit();
}
echo 'Connected to migration database.' . "\n";
$odb->query("SHOW TABLES LIKE 'access_codes';");
if ($odb->num_rows() > 0) {
    $AdminAccesCode = '';
    if (count($rMigrateOptions) == 0) {
        $rMigrateOptions = $rXUITableList;
    }
    $rItemCount = 0;
    foreach ($rXUITableList as $rTable) {
        $odb->query('SHOW TABLES LIKE ?;', $rTable);
        if ($odb->num_rows() > 0) {
            $odb->query('SELECT COUNT(*) AS `count` FROM `' . $rTable . '`;');
            $rItemCount += (intval($odb->get_row()['count']) ?: 0);
        }
    }
    if ($rItemCount == 0) {
        echo "\n" . "Couldn't find anything to migrate in the `xc_vm_migrate` database. Please ensure you restore your backup to that database specifically." . "\n\n";
        exit();
    }
    echo "\n" . 'Migrating database to \XC_VM...' . "\n\n";

    if (in_array('access_codes', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `access_codes`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `access_codes`;');
            echo 'Add ' . number_format(count($rResults), 0) . ' access codes.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    if ($rResult['type'] == 0) {
                        $AdminAccesCode = $rResult['code'];
                    }
                    $rResult = QueryHelper::verifyPostTable('access_codes', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `access_codes`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                    AuthRepository::updateCodes();
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('users', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `users`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `users`;');
            echo 'Adding ' . number_format($rCount, 0) . ' users.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }
            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `users` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult = QueryHelper::verifyPostTable('users', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `users`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('blocked_ips', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `blocked_ips`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `blocked_ips`;');
            echo 'Blocking ' . number_format(count($rResults), 0) . ' IP addresses.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('blocked_ips', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `blocked_ips`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('blocked_uas', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `blocked_uas`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `blocked_uas`;');
            echo 'Blocking ' . number_format(count($rResults), 0) . ' user-agents.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('blocked_uas', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `blocked_uas`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('blocked_isps', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `blocked_isps`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `blocked_isps`;');
            echo 'Blocking ' . number_format(count($rResults), 0) . " ISP's." . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('blocked_isps', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `blocked_isps`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('bouquets', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `bouquets`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `bouquets`;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' bouquets.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('bouquets', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('enigma2_devices', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `enigma2_devices`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `enigma2_devices`;');
            echo 'Authorising ' . number_format($rCount, 0) . ' enigma devices.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }
            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `enigma2_devices` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult = QueryHelper::verifyPostTable('enigma2_devices', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `enigma2_devices`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('mag_devices', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `mag_devices`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `mag_devices`;');
            echo 'Authorising ' . number_format($rCount, 0) . ' MAG devices.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }
            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `mag_devices` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult = QueryHelper::verifyPostTable('mag_devices', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `mag_devices`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('epg', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `epg`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `epg`;');
            echo 'Processing ' . number_format(count($rResults), 0) . ' EPG URLs.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('epg', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `epg`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('users_groups', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `users_groups`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `users_groups`;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' user groups.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('users_groups', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `users_groups`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('users_packages', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `users_packages`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `users_packages`;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' user packages.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('users_packages', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `users_packages`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('rtmp_ips', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `rtmp_ips`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `rtmp_ips`;');
            echo 'Authorising ' . number_format(count($rResults), 0) . ' RTMP IPs.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('rtmp_ips', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `rtmp_ips`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('streams_series', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `streams_series`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams_series`;');
            echo 'Adding ' . number_format($rCount, 0) . ' TV series.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }
            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `streams_series` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult = QueryHelper::verifyPostTable('streams_series', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `streams_series`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('streams_episodes', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `streams_episodes`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams_episodes`;');
            echo 'Adding ' . number_format($rCount, 0) . ' episodes.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }
            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `streams_episodes` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult = QueryHelper::verifyPostTable('streams_episodes', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `streams_episodes`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('servers', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `servers` ORDER BY `id` ASC;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $rMain = false;
            $db->query('TRUNCATE `servers`;');
            echo 'Moving ' . number_format(count($rResults), 0) . ' servers.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('servers', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('streams', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `streams`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams`;');
            echo 'Adding ' . number_format($rCount, 0) . ' streams.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }
            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `streams` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult = QueryHelper::verifyPostTable('streams', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `streams`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('streams_options', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `streams_options`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams_options`;');
            echo 'Attributing ' . number_format($rCount, 0) . ' options to streams.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }
            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `streams_options` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult = QueryHelper::verifyPostTable('streams_options', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `streams_options`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('streams_servers', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `streams_servers`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams_servers`;');
            echo 'Allocating ' . number_format($rCount, 0) . ' streams to servers.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }
            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `streams_servers` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult['stream_status'] = 0;
                        $rResult['stream_started'] = null;
                        $rResult['monitor_pid'] = null;
                        if ($rResult['pid'] < 0) {
                            $rResult['pid'] = null;
                        }
                        $rResult = QueryHelper::verifyPostTable('streams_servers', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `streams_servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('streams_categories', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `streams_categories`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `streams_categories`;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' categories.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('streams_categories', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('tickets', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `tickets`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `tickets`;');
            echo 'Posting ' . number_format(count($rResults), 0) . ' tickets.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('tickets', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `tickets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('tickets_replies', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `tickets_replies`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `tickets_replies`;');
            echo 'Posting ' . number_format(count($rResults), 0) . ' replies.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('tickets_replies', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `tickets_replies`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('profiles', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `profiles`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `profiles`;');
            echo 'Generating ' . number_format(count($rResults), 0) . ' transcoding profiles.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('profiles', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `profiles`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('providers', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `providers`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `providers`;');
            echo 'Generating ' . number_format(count($rResults), 0) . ' providers.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('providers', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `providers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('lines', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `lines`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `lines`;');
            echo 'Adding ' . number_format($rCount, 0) . ' lines.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }
            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `lines` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult['stream_status'] = 0;
                        $rResult['stream_started'] = null;
                        $rResult['monitor_pid'] = null;
                        if ($rResult['pid'] < 0) {
                            $rResult['pid'] = null;
                        }
                        $rResult = QueryHelper::verifyPostTable('lines', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `lines`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('watch_folders', $rMigrateOptions)) {
        $odb->query("SHOW TABLES LIKE 'watch_folders';");
        if ($odb->num_rows() > 0) {
            $odb->query('SELECT COUNT(*) AS `count` FROM `watch_folders`;');
            $rCount = $odb->get_row()['count'];
            if ($rCount > 0) {
                $db->query('TRUNCATE `watch_folders`;');
                echo 'Adding ' . number_format($rCount, 0) . ' folders to watch.' . "\n";
                $odb->query('SELECT * FROM `watch_folders`;');
                $rResults = $odb->get_rows();
                foreach ($rResults as $rResult) {
                    $rResult = QueryHelper::verifyPostTable('watch_folders', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `watch_folders`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                }
            }
        }
    }
} else {
    if (count($rMigrateOptions) == 0) {
        $rMigrateOptions = $rTableList;
    }
    $rItemCount = 0;
    foreach ($rTableList as $rTable) {
        $odb->query('SHOW TABLES LIKE ?;', $rTable);
        if ($odb->num_rows() > 0) {
            $odb->query('SELECT COUNT(*) AS `count` FROM `' . $rTable . '`;');
            $rItemCount += (intval($odb->get_row()['count']) ?: 0);
        }
    }
    if ($rItemCount == 0) {
        echo "\n" . "Couldn't find anything to migrate in the `xc_vm_migrate` database. Please ensure you restore your backup to that database specifically." . "\n\n";
        exit();
    }
    echo "\n" . 'Migrating database to \XC_VM...' . "\n\n";

    echo 'Remapping bouquets.' . "\n";
    $rSeriesMap = $rBouquetMap = array();
    $odb->query('SELECT `id`, `type` FROM `streams`;');
    $rStreams = $odb->get_rows();
    foreach ($rStreams as $rStream) {
        $rBouquetMap[intval($rStream['id'])] = intval($rStream['type']);
    }
    $odb->query('SELECT `id` FROM `series`;');
    $rSeries = $odb->get_rows();
    foreach ($rSeries as $rSeriesArr) {
        $rSeriesMap[] = intval($rSeriesArr['id']);
    }
    if (in_array('reg_users', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `reg_users`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `users`;');
            echo 'Adding ' . number_format($rCount, 0) . ' users.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }
            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `reg_users` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult = QueryHelper::verifyPostTable('users', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `users`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('members', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `members`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `users`;');
            echo 'Adding ' . number_format($rCount, 0) . ' users.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `members` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult = QueryHelper::verifyPostTable('users', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `users`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('blocked_ips', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `blocked_ips`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `blocked_ips`;');
            echo 'Blocking ' . number_format(count($rResults), 0) . ' IP addresses.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('blocked_ips', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `blocked_ips`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('blocked_user_agents', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `blocked_user_agents`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `blocked_uas`;');
            echo 'Blocking ' . number_format(count($rResults), 0) . ' user-agents.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('blocked_uas', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `blocked_uas`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('isp_addon', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `isp_addon`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `blocked_isps`;');
            echo 'Blocking ' . number_format(count($rResults), 0) . " ISP's." . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('blocked_isps', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `blocked_isps`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('blocked_isps', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `blocked_isps`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `blocked_isps`;');
            echo 'Blocking ' . number_format(count($rResults), 0) . " ISP's." . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('blocked_isps', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `blocked_isps`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('bouquets', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `bouquets`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `bouquets`;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' bouquets.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rChannels = json_decode($rResult['bouquet_channels'], true);
                    $rResult['bouquet_radios'] = array();
                    $rResult['bouquet_movies'] = $rResult['bouquet_radios'];
                    $rResult['bouquet_channels'] = $rResult['bouquet_movies'];
                    foreach ($rChannels as $rStreamID) {
                        if (!isset($rBouquetMap[intval($rStreamID)])) {
                        } else {
                            $rType = array(1 => 'channels', 2 => 'movies', 3 => 'channels', 4 => 'radio')[$rBouquetMap[intval($rStreamID)]];
                            if (!$rType) {
                            } else {
                                $rResult['bouquet_' . $rType][] = intval($rStreamID);
                            }
                        }
                    }
                    $rSeries = json_decode($rResult['bouquet_series'], true);
                    $rResult['bouquet_series'] = array();
                    foreach ($rSeries as $rSeriesID) {
                        if (!in_array(intval($rSeriesID), $rSeriesMap)) {
                        } else {
                            $rResult['bouquet_series'][] = intval($rSeriesID);
                        }
                    }
                    foreach (array('channels', 'movies', 'radios', 'series') as $rType) {
                        if ($rResult['bouquet_' . $rType]) {
                        } else {
                            $rResult['bouquet_' . $rType] = '[]';
                        }
                    }
                    $rResult = QueryHelper::verifyPostTable('bouquets', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `bouquets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('enigma2_devices', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `enigma2_devices`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `enigma2_devices`;');
            echo 'Authorising ' . number_format($rCount, 0) . ' enigma devices.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `enigma2_devices` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult['lock_device'] = 1;
                        $rResult = QueryHelper::verifyPostTable('enigma2_devices', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `enigma2_devices`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('mag_devices', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `mag_devices`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `mag_devices`;');
            echo 'Authorising ' . number_format($rCount, 0) . ' MAG devices.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `mag_devices` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult['mac'] = base64_decode($rResult['mac']);
                        $rResult['lock_device'] = 1;
                        if (0 >= $rResult['user_id']) {
                        } else {
                            $rResult = QueryHelper::verifyPostTable('mag_devices', $rResult);
                            $rPrepare = QueryHelper::prepareArray($rResult);
                            $rQuery = 'INSERT INTO `mag_devices`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                            $db->query($rQuery, ...$rPrepare['data']);
                        }
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('epg', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `epg`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `epg`;');
            echo 'Processing ' . number_format(count($rResults), 0) . ' EPG URLs.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('epg', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `epg`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('epg_sources', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `epg_sources`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `epg`;');
            echo 'Processing ' . number_format(count($rResults), 0) . ' EPG URLs.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('epg', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `epg`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('member_groups', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `member_groups` WHERE `can_delete` = 1;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('DELETE FROM `users_groups` WHERE `can_delete` = 1;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' user groups.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult['can_view_vod'] = $rResult['reset_stb_data'];
                    $rResult['allow_restrictions'] = 1;
                    $rResult['allow_change_username'] = 1;
                    $rResult['allow_change_password'] = 1;
                    $rResult['minimum_username_length'] = 8;
                    $rResult['minimum_password_length'] = 8;
                    $rResult = QueryHelper::verifyPostTable('users_groups', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `users_groups`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('groups', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `groups` WHERE `can_delete` = 1;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('DELETE FROM `users_groups` WHERE `can_delete` = 1;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' user groups.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult['can_view_vod'] = $rResult['reset_stb_data'];
                    $rResult['allow_restrictions'] = 1;
                    $rResult['allow_change_username'] = 1;
                    $rResult['allow_change_password'] = 1;
                    $rResult['minimum_username_length'] = 8;
                    $rResult['minimum_password_length'] = 8;
                    $rResult = QueryHelper::verifyPostTable('users_groups', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `users_groups`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('groups', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `groups` WHERE `can_delete` = 1;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('DELETE FROM `users_groups` WHERE `can_delete` = 1;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' user groups.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult['can_view_vod'] = $rResult['reset_stb_data'];
                    $rResult['allow_restrictions'] = 1;
                    $rResult['allow_change_username'] = 1;
                    $rResult['allow_change_password'] = 1;
                    $rResult['minimum_username_length'] = 8;
                    $rResult['minimum_password_length'] = 8;
                    $rResult = QueryHelper::verifyPostTable('users_groups', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `users_groups`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('packages', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `packages`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `users_packages`;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' user packages.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    if ($rResult['can_gen_mag']) {
                        $rResult['is_mag'] = 1;
                    } else {
                        $rResult['is_mag'] = 0;
                    }
                    if ($rResult['can_gen_e2']) {
                        $rResult['is_e2'] = 1;
                    } else {
                        $rResult['is_e2'] = 0;
                    }
                    if ($rResult['only_mag'] || $rResult['only_e2']) {
                        $rResult['is_line'] = 0;
                    } else {
                        $rResult['is_line'] = 1;
                    }
                    $rResult['lock_device'] = 1;
                    $rResult['check_compatible'] = 1;
                    if (count(json_decode($rResult['output_formats'], true)) != 0) {
                    } else {
                        $rResult['output_formats'] = '[1,2,3]';
                    }
                    $rResult = QueryHelper::verifyPostTable('users_packages', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `users_packages`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('rtmp_ips', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `rtmp_ips`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `rtmp_ips`;');
            echo 'Authorising ' . number_format(count($rResults), 0) . ' RTMP IPs.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('rtmp_ips', $rResult);
                    $rResult['push'] = 1;
                    $rResult['pull'] = 1;
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `rtmp_ips`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('series', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `series`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams_series`;');
            echo 'Adding ' . number_format($rCount, 0) . ' TV series.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `series` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult['category_id'] = '[' . intval($rResult['category_id']) . ']';
                        $rResult['release_date'] = $rResult['releaseDate'];
                        if ($rResult['tmdb_id'] != 0) {
                        } else {
                            $rResult['tmdb_id'] = null;
                        }
                        $rResult = QueryHelper::verifyPostTable('streams_series', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT IGNORE INTO `streams_series`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('series_episodes', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `series_episodes`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams_episodes`;');
            echo 'Adding ' . number_format($rCount, 0) . ' episodes.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `series_episodes` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult['episode_num'] = $rResult['sort'];
                        $rResult = QueryHelper::verifyPostTable('streams_episodes', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `streams_episodes`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('streaming_servers', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `streaming_servers`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $rMain = false;
            $db->query('TRUNCATE `servers`;');
            echo 'Moving ' . number_format(count($rResults), 0) . ' servers.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult['server_type'] = 0;
                    $rResult['parent_id'] = null;
                    $rResult['http_broadcast_port'] = 80;
                    $rResult['https_broadcast_port'] = 443;
                    $rResult['rtmp_port'] = 8880;
                    $rResult['total_services'] = 4;
                    $rResult['http_ports_add'] = null;
                    $rResult['https_ports_add'] = null;
                    if ($rResult['can_delete'] == 0 && !$rMain) {
                        $rResult['is_main'] = 1;
                        $rMain = true;
                    } else {
                        $rResult['is_main'] = 0;
                    }
                    $rResult = QueryHelper::verifyPostTable('servers', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('servers', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `servers` ORDER BY `id` ASC;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $rMain = false;
            $db->query('TRUNCATE `servers`;');
            echo 'Moving ' . number_format(count($rResults), 0) . ' servers.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult['server_type'] = 0;
                    $rResult['parent_id'] = null;
                    $rResult['http_broadcast_port'] = 80;
                    $rResult['https_broadcast_port'] = 443;
                    $rResult['rtmp_port'] = 8880;
                    $rResult['total_services'] = 4;
                    $rResult['http_ports_add'] = null;
                    $rResult['https_ports_add'] = null;
                    if (!$rMain) {
                        $rResult['is_main'] = 1;
                        $rMain = true;
                    } else {
                        $rResult['is_main'] = 0;
                    }
                    $rResult = QueryHelper::verifyPostTable('servers', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    $rCreatedOptions = array();
    if (in_array('streams', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `streams`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams`;');
            echo 'Adding ' . number_format($rCount, 0) . ' streams.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `streams` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        try {
                            $rExternal = json_decode($rResult['external_push'], true);
                            if ($rExternal) {
                            } else {
                                $rResult['external_push'] = '{}';
                            }
                            $rResult['category_id'] = '[' . intval($rResult['category_id']) . ']';
                            $rResult['movie_properties'] = $rResult['movie_propeties'];
                            if (!$rResult['target_container']) {
                            } else {
                                list($rResult['target_container']) = json_decode($rResult['target_container'], true);
                            }
                            $rCreatedOptions[$rResult['id']] = $rResult['cchannel_rsources'];
                            $rResult = QueryHelper::verifyPostTable('streams', $rResult);
                            $rPrepare = QueryHelper::prepareArray($rResult);
                            $rQuery = 'INSERT INTO `streams`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                            $db->query($rQuery, ...$rPrepare['data']);
                        } catch (\Exception $e) {
                            echo 'Error: ' . $e . "\n";
                        }
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('streams_options', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `streams_options`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams_options`;');
            echo 'Attributing ' . number_format($rCount, 0) . ' options to streams.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `streams_options` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rResult = QueryHelper::verifyPostTable('streams_options', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `streams_options`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('streams_sys', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `streams_sys`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams_servers`;');
            echo 'Allocating ' . number_format($rCount, 0) . ' streams to servers.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `streams_sys` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    if (0 >= count($rResults)) {
                    } else {
                        foreach ($rResults as $rResult) {
                            if ($rResult['parent_id'] && $rResult['parent_id'] != 0) {
                            } else {
                                $rResult['parent_id'] = null;
                            }
                            if (!isset($rCreatedOptions[$rResult['stream_id']])) {
                            } else {
                                $rResult['cchannel_rsources'] = $rCreatedOptions[$rResult['stream_id']];
                            }
                            $rResult['custom_ffmpeg'] = '';
                            $rResult['stream_status'] = 0;
                            $rResult['stream_started'] = null;
                            $rResult['monitor_pid'] = null;
                            if ($rResult['pid'] < 0) {
                                $rResult['pid'] = null;
                            }
                            $rResult = QueryHelper::verifyPostTable('streams_servers', $rResult);
                            $rPrepare = QueryHelper::prepareArray($rResult);
                            $rQuery = 'INSERT INTO `streams_servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                            $db->query($rQuery, ...$rPrepare['data']);
                        }
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('stream_servers', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `stream_servers`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `streams_servers`;');
            echo 'Allocating ' . number_format($rCount, 0) . ' streams to servers.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `stream_servers` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    if (0 >= count($rResults)) {
                    } else {
                        foreach ($rResults as $rResult) {
                            if ($rResult['parent_id'] && $rResult['parent_id'] != 0) {
                            } else {
                                $rResult['parent_id'] = null;
                            }
                            $rResult['stream_status'] = 0;
                            $rResult['stream_started'] = null;
                            $rResult['monitor_pid'] = null;
                            if ($rResult['pid'] > 0) {
                            } else {
                                $rResult['pid'] = null;
                            }
                            $rResult = QueryHelper::verifyPostTable('streams_servers', $rResult);
                            $rPrepare = QueryHelper::prepareArray($rResult);
                            $rQuery = 'INSERT INTO `streams_servers`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                            $db->query($rQuery, ...$rPrepare['data']);
                        }
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('stream_categories', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `stream_categories`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `streams_categories`;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' categories.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('streams_categories', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('categories', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `categories`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `streams_categories`;');
            echo 'Creating ' . number_format(count($rResults), 0) . ' categories.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('streams_categories', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `streams_categories`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('tickets', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `tickets`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `tickets`;');
            echo 'Posting ' . number_format(count($rResults), 0) . ' tickets.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('tickets', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `tickets`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('tickets_replies', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `tickets_replies`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `tickets_replies`;');
            echo 'Posting ' . number_format(count($rResults), 0) . ' replies.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('tickets_replies', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `tickets_replies`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('transcoding_profiles', $rMigrateOptions)) {
        $odb->query('SELECT * FROM `transcoding_profiles`;');
        $rResults = $odb->get_rows();
        if (count($rResults) > 0) {
            $db->query('TRUNCATE `profiles`;');
            echo 'Generating ' . number_format(count($rResults), 0) . ' transcoding profiles.' . "\n";
            foreach ($rResults as $rResult) {
                try {
                    $rResult = QueryHelper::verifyPostTable('profiles', $rResult);
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `profiles`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    $rOutput = array();
    if (in_array('user_output', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `user_output`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            echo 'Attributing ' . number_format($rCount, 0) . ' output options to lines.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `user_output` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        $rOutput[$rResult['user_id']][] = $rResult['access_output_id'];
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
        }
    }
    if (in_array('users', $rMigrateOptions)) {
        $odb->query('SELECT COUNT(*) AS `count` FROM `users`;');
        $rCount = $odb->get_row()['count'];
        if ($rCount > 0) {
            $db->query('TRUNCATE `lines`;');
            echo 'Adding ' . number_format($rCount, 0) . ' lines.' . "\n";
            $rSteps = [];
            $stepSize = 1000;
            for ($i = 0; $i < $rCount; $i += $stepSize) {
                $rSteps[] = $i;
            }
            if (empty($rSteps)) {
                $rSteps = [0];
            }

            foreach ($rSteps as $rStep) {
                try {
                    $odb->query('SELECT * FROM `users` LIMIT ' . $rStep . ', 1000;');
                    $rResults = $odb->get_rows();
                    foreach ($rResults as $rResult) {
                        if (!empty($rResult['isp_desc'])) {
                        } else {
                            $rResult['isp_desc'] = null;
                        }
                        if (!isset($rOutput[$rResult['id']])) {
                        } else {
                            $rResult['allowed_outputs'] = '[' . implode(',', $rOutput[$rResult['id']]) . ']';
                        }
                        if (!isset($rResult['output'])) {
                        } else {
                            $rResult['allowed_outputs'] = $rResult['output'];
                        }
                        $rResult['bouquet'] = '[' . implode(',', array_map('intval', json_decode($rResult['bouquet'], true))) . ']';
                        $rResult = QueryHelper::verifyPostTable('lines', $rResult);
                        $rPrepare = QueryHelper::prepareArray($rResult);
                        $rQuery = 'INSERT INTO `lines`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                        $db->query($rQuery, ...$rPrepare['data']);
                    }
                } catch (\Exception $e) {
                    echo 'Error: ' . $e . "\n";
                }
            }
            try {
            } catch (\Exception $e) {
                echo 'Error: ' . $e . "\n";
            }
        }
    }
    if (in_array('watch_folders', $rMigrateOptions)) {
        $odb->query("SHOW TABLES LIKE 'watch_folders';");
        if (0 >= $odb->num_rows()) {
        } else {
            $odb->query('SELECT COUNT(*) AS `count` FROM `watch_folders`;');
            $rCount = $odb->get_row()['count'];
            if ($rCount > 0) {
                $db->query('TRUNCATE `watch_folders`;');
                echo 'Adding ' . number_format($rCount, 0) . ' folders to watch.' . "\n";
                $odb->query('SELECT * FROM `watch_folders`;');
                $rResults = $odb->get_rows();
                foreach ($rResults as $rResult) {
                    $rResult = QueryHelper::verifyPostTable('watch_folders', $rResult);
                    $rResult['bouquets'] = '[' . implode(',', array_map('intval', json_decode($rResult['bouquets'], true))) . ']';
                    $rResult['fb_bouquets'] = '[' . implode(',', array_map('intval', json_decode($rResult['fb_bouquets'], true))) . ']';
                    $rPrepare = QueryHelper::prepareArray($rResult);
                    $rQuery = 'INSERT INTO `watch_folders`(' . $rPrepare['columns'] . ') VALUES(' . $rPrepare['placeholder'] . ');';
                    $db->query($rQuery, ...$rPrepare['data']);
                }
            }
        }
    }
}
try {
    $odb->query('SELECT * FROM `settings` LIMIT 1;');
    $rSettings = $odb->get_row();
    $db->query('UPDATE `settings` SET `server_name` = ?, `default_timezone` = ?;', $rSettings['server_name'], $rSettings['default_timezone']);
} catch (\Exception $e) {
    echo 'Error: ' . $e . "\n";
}
try {
    $odb->query("SHOW TABLES LIKE 'admin_settings';");
    if ($odb->num_rows() > 0) {
        $rAdminSettings = array();
        $odb->query('SELECT * FROM `admin_settings`;');
        foreach ($odb->get_rows() as $rRow) {
            $rAdminSettings[$rRow['type']] = $rRow['value'];
        }
        if (!(0 < strlen($rAdminSettings['recaptcha_v2_secret_key']) && 0 < strlen($rAdminSettings['recaptcha_v2_site_key']))) {
        } else {
            $db->query('UPDATE `settings` SET `recaptcha_v2_secret_key` = ?, `recaptcha_v2_site_key` = ?;', $rAdminSettings['recaptcha_v2_secret_key'], $rAdminSettings['recaptcha_v2_site_key']);
        }
    }
} catch (\Exception $e) {
    echo 'Error: ' . $e . "\n";
}
if (in_array('access_codes', $rMigrateOptions)) {
    echo "\n" . 'Admin acces code: ' . $AdminAccesCode;
}
echo "\n" . 'Migration has been completed!' . "\n\n" . 'Your settings have been reset to the \XC_VM default, please take some time to review the settings page and make the desired changes.' . "\n";

file_put_contents(TMP_PATH . '.migration.status', 2);
if (is_object($odb)) {
    $odb->close_mysql();
}
