<?php
/* ============================================================
 * Larspeenghar — load-test seeder
 * Generates synthetic animals (with real pedigree links) so you can
 * prove the system runs at 3,000,000 cows on your own server.
 *
 * RUN FROM THE COMMAND LINE (best for big counts):
 *     php seed.php 3000000
 *     php seed.php 3000000 --owner=1
 *
 * OR via browser in chunks (guarded by config.php 'migrate_key'):
 *     seed.php?key=SECRET&count=100000&start=0
 *     ...repeat increasing start until done.
 *
 * Linking: each new animal's sire/dam point at random EARLIER animals,
 * so a deep, connected pedigree exists to exercise the recursive walks.
 * DELETE THIS FILE after load-testing.
 * ============================================================ */

@set_time_limit(0);
@ini_set('memory_limit', '512M');
ignore_user_abort(true);

require __DIR__ . '/db.php';
$cli = (php_sapi_name() === 'cli');
$cfg = file_exists(__DIR__ . '/config.php') ? include __DIR__ . '/config.php' : [];

/* ---- args / auth ---- */
if ($cli) {
    $count = isset($argv[1]) ? (int)$argv[1] : 100000;
    $start = 0;
    $ownerId = null;
    foreach ($argv as $a) {
        if (strpos($a, '--owner=') === 0) $ownerId = (int)substr($a, 8);
        if (strpos($a, '--start=') === 0) $start = (int)substr($a, 8);
    }
} else {
    header('Content-Type: text/plain; charset=utf-8');
    $secret = $cfg['migrate_key'] ?? '';
    if ($secret === '' || ($_GET['key'] ?? '') !== $secret) {
        http_response_code(403);
        exit("Forbidden. Set 'migrate_key' in config.php and pass ?key=...\n");
    }
    $count = (int)($_GET['count'] ?? 100000);
    $start = (int)($_GET['start'] ?? 0);
    $ownerId = isset($_GET['owner']) ? (int)$_GET['owner'] : null;
}

$pdo = lp_db();
$BATCH = 2000;          // rows per multi-insert
$LINK_WINDOW = 200000;  // pick parents from up to this many earlier ids

$breeds = ['Holstein', 'Holstein', 'Holstein', 'Montbeliard', 'Local'];
$provinces = ['Kabul', 'Herat', 'Balkh', 'Nangarhar', 'Kandahar', 'Kunduz'];

function say($s) { echo $s . "\n"; @ob_flush(); @flush(); }

// Highest existing id so links can reference real rows.
$maxId = (int)$pdo->query("SELECT COALESCE(MAX(id),0) FROM animals")->fetchColumn();
say("Seeding $count animals (current max id = $maxId)…");

$cols = "reg_id,ear_tag,name,breed,sex,role,dob,owner_id,province,sire_id,dam_id,milk_305,fat_pct,prot_pct";
$t0 = microtime(true);
$made = 0;

$pdo->beginTransaction();
$rowsql = "(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
for ($i = 0; $i < $count; $i += $BATCH) {
    $n = min($BATCH, $count - $i);
    $ph = implode(',', array_fill(0, $n, $rowsql));
    $args = [];
    for ($j = 0; $j < $n; $j++) {
        $seq = $maxId + $i + $j + 1;
        $sex = (mt_rand(0, 100) < 80) ? 'Female' : 'Male';
        $role = $sex === 'Male' ? 'Sire' : 'Cow';
        $breed = $breeds[array_rand($breeds)];
        // parents: random earlier ids (or NULL near the start)
        $lo = max(1, $seq - $LINK_WINDOW);
        $hi = $seq - 1;
        $sire = $hi > $lo ? mt_rand($lo, $hi) : null;
        $dam = $hi > $lo ? mt_rand($lo, $hi) : null;
        $year = 2000 + (int)floor((($seq) / max(1, $count)) * 24); // spread births 2000-2024
        $dob = sprintf('%04d-%02d-%02d', $year, mt_rand(1, 12), mt_rand(1, 28));
        $milk = $sex === 'Female' ? mt_rand(6000, 14000) : null;
        $fat = $sex === 'Female' ? round(mt_rand(330, 430) / 100, 2) : null;
        $prot = $sex === 'Female' ? round(mt_rand(300, 360) / 100, 2) : null;
        array_push(
            $args,
            'TEST-' . $seq,                       // reg_id
            'T' . $seq,                            // ear_tag
            strtoupper($breed[0]) . ' COW ' . $seq, // name
            $breed, $sex, $role, $dob, $ownerId,
            $provinces[array_rand($provinces)],
            $sire, $dam, $milk, $fat, $prot
        );
    }
    $st = $pdo->prepare("INSERT INTO animals ($cols) VALUES $ph");
    $st->execute($args);
    $made += $n;
    if ($made % 50000 === 0 || $made === $count) {
        $pdo->commit();
        $rate = $made / max(0.001, microtime(true) - $t0);
        say(sprintf("  %s / %s  (%.0f rows/sec)", number_format($made), number_format($count), $rate));
        $pdo->beginTransaction();
    }
}
$pdo->commit();
say(sprintf("✅ Done. Inserted %s animals in %.1fs.", number_format($made), microtime(true) - $t0));
say("Now run:  php recompute.php   (to populate inbreeding for the herd report)");
say("DELETE seed.php and recompute.php when finished load-testing.");
