#!/usr/bin/env php
<?php

/**
 * Background script to run cPanel backup imports
 * 
 * Usage: php run-cpanel-import.php <import_id> <username> <backup_file_path>
 */

// Check command line arguments
if ($argc !== 4) {
    echo "Usage: php run-cpanel-import.php <import_id> <username> <backup_file_path>\n";
    exit(1);
}

$importId = $argv[1];
$username = $argv[2];
$backupFilePath = $argv[3];

// Include required files. We deliberately use the deployed /docker/whp/web/
// paths for everything that other WHP libs (emailmgmt, ApiKeyManager, etc.)
// also load — otherwise PHP's require_once dedup-by-resolved-path lets the
// same class get declared twice and fataling at the second load. The
// CpanelBackupImporter itself is in this repo's git checkout under
// /root/whp/web-files/, but the rsync into /docker/whp/web/ is identical,
// so loading from /docker side keeps every transitive include unified.
require_once '/docker/whp/web/configs/config.php';
require_once '/docker/whp/web/libs/CpanelBackupImporter.php';
require_once '/docker/whp/web/libs/mysqlmgmt.php';

// Log function (define early so we can use it everywhere)
function logMessage($message, $level = 'info') {
    global $importId;
    $timestamp = date('Y-m-d H:i:s');
    $logEntry = "[$timestamp] [$level] $message";
    echo "$logEntry\n";
    error_log("CpanelImport[$importId]: $logEntry");
}

// Connect to database using the same method as other WHP scripts
try {
    $MySQLMgmt = new mysqlmgmt();
    $pdo = $MySQLMgmt->getMySQLConnection();
    
    if (!$pdo) {
        throw new Exception('Failed to establish database connection');
    }
    
    // Select the whp database
    $pdo->exec("USE whp");
    
    logMessage("Database connection established successfully");
} catch (Exception $e) {
    logMessage("Database connection failed: " . $e->getMessage(), 'error');
    
    // Try to update status if possible, but don't fail if we can't
    if (isset($pdo) && $pdo) {
        updateImportStatus($importId, 'failed', 0, 'Database connection failed: ' . $e->getMessage());
    }
    exit(1);
}

// Update import status
function updateImportStatus($importId, $status, $progress = null, $errorMessage = null, $log = null) {
    global $pdo;
    
    $sql = "UPDATE cpanel_imports SET status = ?";
    $params = [$status];
    
    if ($progress !== null) {
        $sql .= ", progress = ?";
        $params[] = $progress;
    }
    
    if ($errorMessage !== null) {
        $sql .= ", error_message = ?";
        $params[] = $errorMessage;
    }
    
    if ($log !== null) {
        $sql .= ", log = ?";
        $params[] = json_encode($log);
    }
    
    if ($status === 'completed' || $status === 'failed') {
        $sql .= ", completed_at = NOW()";
    }
    
    $sql .= " WHERE import_id = ?";
    $params[] = $importId;
    
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
    } catch (PDOException $e) {
        error_log("Failed to update import status: " . $e->getMessage());
    }
}

// Log function moved to top of file for early availability

// Main import process
try {
    logMessage("Starting cPanel backup import for user: $username");
    updateImportStatus($importId, 'running', 5);
    
    // Validate input
    if (!file_exists($backupFilePath)) {
        throw new Exception("Backup file not found: $backupFilePath");
    }
    
    if (!is_readable($backupFilePath)) {
        throw new Exception("Backup file is not readable: $backupFilePath");
    }
    
    logMessage("Backup file validated: " . basename($backupFilePath));
    updateImportStatus($importId, 'running', 10);
    
    // Create importer instance
    $importer = new CpanelBackupImporter($pdo, $username);

    // Wire the import_id BEFORE importBackup so the importer's per-stage
    // reportProgress() updates actually land on whp.cpanel_imports while
    // the long-running phases run. Otherwise the panel sits at 15% until
    // the worker writes 100% at the end, and the user thinks it's stuck.
    $importer->setImportId($importId);

    // Run the import
    logMessage("Starting backup import process");
    updateImportStatus($importId, 'running', 15);

    $result = $importer->importBackup($backupFilePath);

    if ($result['success']) {
        logMessage("Import completed successfully");
        logMessage("Domains imported: " . $result['domains_imported']);
        logMessage("Sites created: " . $result['sites_created']);

        // ---- Email-stage drivers + summary writer + optional summary email ----
        // The mailbox/forwarder importers and summary helpers were added in
        // tasks 7-9. They run AFTER the base import succeeds; failures here
        // are treated as non-fatal — the base import is already on disk.
        require_once '/docker/whp/web/libs/CpanelImportSummary.php';
        require_once '/docker/whp/web/libs/CpanelImportEmailTemplate.php';

        // setImportId was already called pre-importBackup so the per-stage
        // progress reports fired during the bulk of the import. No need
        // to call it again here.
        updateImportStatus($importId, 'running', 90);

        $domains = $importer->getImportedDomains();
        logMessage('Starting email import (mailboxes + forwarders) for ' . count($domains) . ' domains');
        try {
            $importer->importEmailAccounts($domains);
            $importer->importEmailForwarders($domains);
        } catch (Exception $e) {
            // Don't bring down a successful base import because of an email-stage error.
            logMessage('Email-stage import threw: ' . $e->getMessage(), 'error');
        }

        // Build the canonical summary structure.
        $emailState = $importer->getEmailSummary();
        $summary = [
            'import_id'    => $importId,
            'username'     => $username,
            'completed_at' => gmdate('c'),
            'totals'       => $importer->getCounts(),
            'sites'        => $importer->getImportedSites(),
            'databases'    => $importer->getImportedDatabases(),
            'dns'          => $importer->getDnsSummary(),
            'mailboxes'    => $emailState['mailboxes'] ?? [],
            'forwarders'   => $emailState['forwarders'] ?? [],
            'warnings'     => array_merge(
                $emailState['warnings'] ?? [],
                $importer->getSiteWarnings()
            ),
        ];

        try {
            CpanelImportSummary::writeSummary($importId, $summary);
            logMessage('Wrote summary file: ' . CpanelImportSummary::summaryPath($importId));
            updateImportStatus($importId, 'running', 95);
        } catch (Exception $e) {
            logMessage('Failed to write summary file: ' . $e->getMessage(), 'error');
            // Non-fatal — the import itself succeeded.
        }

        // NOW it's safe to wipe the extraction tempdir. importBackup() no
        // longer cleans up on success because the email-import phase above
        // needs the files. Do it here, after the summary is on disk.
        try {
            $importer->cleanup();
        } catch (Exception $e) {
            logMessage('cleanup() threw: ' . $e->getMessage(), 'error');
        }

        // Email the summary if the form requested it.
        try {
            $stmt = $pdo->prepare("SELECT email_summary_to FROM whp.cpanel_imports WHERE import_id = ?");
            $stmt->execute([$importId]);
            $emailTo = $stmt->fetchColumn() ?: null;
        } catch (Exception $e) {
            logMessage('Could not look up email_summary_to: ' . $e->getMessage(), 'warning');
            $emailTo = null;
        }

        if ($emailTo) {
            if (!class_exists('SmtpMailer')) {
                require_once '/docker/whp/web/libs/smtp_mailer.php';
            }
            // Worker has no HTTP_HOST; prefer a configured panel hostname,
            // else fall back to gethostname() — admins know which panel
            // they are operating.
            $panelHost = (defined('PANEL_HOST') && PANEL_HOST) ? PANEL_HOST : gethostname();
            $resultsUrl = "https://$panelHost/index.php?page=cpanel-import-results&import_id="
                        . urlencode($importId);
            try {
                $rendered = CpanelImportEmailTemplate::render($summary, $resultsUrl);
                $smtpConfig = SmtpMailer::loadConfig();
                if ($smtpConfig === null) {
                    logMessage("SMTP not configured/disabled — skipping summary email to $emailTo", 'warning');
                } else {
                    $mailer = new SmtpMailer($smtpConfig);
                    $sendResult = $mailer->send(
                        $emailTo,
                        $rendered['subject'],
                        $rendered['html'],
                        $rendered['text']
                    );
                    if (!empty($sendResult['success'])) {
                        $summary['summary_email_sent_to'] = $emailTo;
                        try {
                            CpanelImportSummary::writeSummary($importId, $summary);
                        } catch (Exception $e) {
                            logMessage('Failed to update summary file with email status: ' . $e->getMessage(), 'warning');
                        }
                        logMessage("Sent import summary email to $emailTo");
                    } else {
                        logMessage('Failed to send summary email: ' . ($sendResult['error'] ?? 'unknown'), 'error');
                    }
                }
            } catch (Exception $e) {
                logMessage('Failed to send summary email: ' . $e->getMessage(), 'error');
                // Non-fatal: the JSON summary on disk is the source of truth.
            }
        }
        // ---- end email-stage block ----

        updateImportStatus($importId, 'completed', 100, null, $result['log']);

        // Clean up uploaded file
        if (file_exists($backupFilePath)) {
            unlink($backupFilePath);
            logMessage("Cleaned up uploaded backup file");
        }

    } else {
        throw new Exception($result['error']);
    }
    
} catch (Exception $e) {
    $errorMessage = $e->getMessage();
    logMessage("Import failed: $errorMessage", 'error');
    
    updateImportStatus($importId, 'failed', null, $errorMessage);
    
    // Clean up uploaded file even on failure
    if (file_exists($backupFilePath)) {
        unlink($backupFilePath);
        logMessage("Cleaned up uploaded backup file after failure");
    }
    
    exit(1);
}

logMessage("cPanel backup import process completed");
exit(0);