#!/usr/bin/env php
<?php
/**
 * CLI-only database setup for aMember Docker.
 *
 * Checks if the database is initialized (am_config table with rows).
 * If not, runs Am_Setup to create tables, import data, and configure defaults.
 * Does NOT write config.php — that is handled by the Docker entrypoint.
 *
 * Required env vars: AM_MYSQL_HOST, AM_MYSQL_DB, AM_MYSQL_USER, AM_MYSQL_PASS
 * Optional: AM_MYSQL_PREFIX, AM_ROOT_DOMAIN, AM_ROOT_PATH,
 *           AM_LICENSE_KEY, AM_ADMIN_EMAIL, AM_ADMIN_PASS, AM_SITE_TITLE
 */

if (!defined('AM_ALLOW_CLI_SETUP')) {
    die("AM_ALLOW_CLI_SETUP constant is not set.\n");
}

$rootDir = dirname(__DIR__, 2);

// Autoloader
$autoloadPath = $rootDir . '/library/vendor/autoload.php';
if (!file_exists($autoloadPath)) {
    fwrite(STDERR, "ERROR: Composer autoloader not found at $autoloadPath\n");
    exit(1);
}
require_once $autoloadPath;

// Read required env vars
$host = getenv('AM_MYSQL_HOST');
$db = getenv('AM_MYSQL_DB');
$user = getenv('AM_MYSQL_USER');
$pass = getenv('AM_MYSQL_PASS');

if (!$host || !$db || !$user) {
    fwrite(STDERR, "ERROR: AM_MYSQL_HOST, AM_MYSQL_DB, and AM_MYSQL_USER are required\n");
    exit(1);
}

if ($pass === false) {
    $pass = '';
}

$prefix = getenv('AM_MYSQL_PREFIX') ?: 'am_';
$port = getenv('AM_MYSQL_PORT') ?: '3306';

// Check if database is already initialized
$dbInitialized = false;
try {
    $pdo = new PDO(
        "mysql:host=$host;port=$port;dbname=$db;charset=utf8",
        $user,
        $pass,
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );

    $stmt = $pdo->query("SHOW TABLES LIKE " . $pdo->quote($prefix . 'config'));
    if ($stmt->rowCount() > 0) {
        $count = $pdo->query("SELECT COUNT(*) FROM `{$prefix}config`")->fetchColumn();
        if ($count > 0) {
            $dbInitialized = true;
        }
    }
} catch (PDOException $e) {
    // Connection or query failed — database may not exist yet or tables missing
    // We'll attempt setup below
}

if ($dbInitialized) {
    echo "Database already initialized. Running schema sync...\n";

    // Run schema sync to apply any new tables/columns from upgrades
    try {
        $dbXmlFiles = [];
        foreach (glob($rootDir . '/application/*/db.xml') as $xmlFile) {
            $dbXmlFiles[] = $xmlFile;
        }

        if (!class_exists('DbSimple_Mypdo', false)) {
            require_once $rootDir . '/library/DbSimple/Generic.php';
        }

        $dbConn = new DbSimple_Mypdo([
            'scheme' => 'mysql',
            'host' => $host,
            'port' => $port,
            'user' => $user,
            'pass' => $pass,
            'path' => $db,
        ]);
        $dbConn->setIdentPrefix($prefix);

        $xmlSchema = new Am_DbSync();
        foreach ($dbXmlFiles as $fn) {
            $xmlContent = file_get_contents($fn);
            if (!$xmlContent) {
                continue;
            }
            // Replace placeholders with safe defaults (not needed for schema sync)
            foreach ([
                Am_Setup::HOST, Am_Setup::DB, Am_Setup::USER, Am_Setup::PASS,
                Am_Setup::PREFIX, Am_Setup::ROOT_URL, Am_Setup::ROOT_SURL,
                Am_Setup::ADMIN_EMAIL, '@ADMIN_LOGIN@', Am_Setup::ADMIN_PASS,
                Am_Setup::LICENSE, Am_Setup::SITE_TITLE,
            ] as $placeholder) {
                $xmlContent = str_replace($placeholder, $dbConn->quote(''), $xmlContent);
            }
            $xmlSchema->parseXml($xmlContent);
        }

        $currentSchema = new Am_DbSync();
        $currentSchema->parseTables($dbConn);

        $diff = $xmlSchema->diff($currentSchema);
        if ($diff->getSql($prefix)) {
            echo "Applying schema changes...\n";
            $diff->apply($dbConn);
            echo "Schema sync complete.\n";
        } else {
            echo "Schema is up to date.\n";
        }
    } catch (Exception $e) {
        fwrite(STDERR, "WARNING: Schema sync failed: " . $e->getMessage() . "\n");
        // Non-fatal — the app may still work with existing schema
    }

    exit(0);
}

// Database not initialized — run full setup
echo "Database not initialized. Running setup...\n";

$rootUrl = (getenv('AM_ROOT_DOMAIN') ?: 'http://localhost') . (getenv('AM_ROOT_PATH') !== false ? getenv('AM_ROOT_PATH') : '/amember');

$config = [
    Am_Setup::HOST => $host,
    Am_Setup::PORT => $port,
    Am_Setup::DB => $db,
    Am_Setup::USER => $user,
    Am_Setup::PASS => $pass,
    Am_Setup::PREFIX => $prefix,
    Am_Setup::CURL => '',
    Am_Setup::ROOT_URL => $rootUrl,
    Am_Setup::ROOT_SURL => $rootUrl,
    Am_Setup::ADMIN_EMAIL => getenv('AM_ADMIN_EMAIL') ?: 'admin@example.com',
    '@ADMIN_LOGIN@' => getenv('AM_ADMIN_LOGIN') ?: 'admin',
    Am_Setup::ADMIN_PASS => getenv('AM_ADMIN_PASS') ?: bin2hex(random_bytes(16)),
    Am_Setup::LICENSE => getenv('AM_LICENSE_KEY') ?: '',
    Am_Setup::SITE_TITLE => getenv('AM_SITE_TITLE') ?: 'aMember',
];

// Log the admin password if auto-generated
if (!getenv('AM_ADMIN_PASS')) {
    echo "Auto-generated admin password: " . $config[Am_Setup::ADMIN_PASS] . "\n";
    echo "Set AM_ADMIN_PASS env var to use a specific password.\n";
}

$dbXmlFiles = [];
foreach (glob($rootDir . '/application/*/db.xml') as $xmlFile) {
    $dbXmlFiles[] = $xmlFile;
}

$setup = new Am_Setup(
    $rootDir . '/setup',
    $rootDir . '/application/configs',
    $dbXmlFiles,
    $config
);

$setup->process(true); // true = skip writing config.php (entrypoint handles that)
echo "Setup complete.\n";
exit(2); // exit code 2 = fresh install (signals entrypoint to run first-run tasks)
