<?php
// Read-only regression baseline for the 668 migrated physical-device records.
// Run on the application server. It never issues INSERT/UPDATE/DELETE queries.
declare(strict_types=1);

$cfg = include '/workspace/wwwroot/tnxlgstyj/project/application/config/prod/tnxlgstyj/database.php';
$db = new PDO(
    'mysql:host='.$cfg['hostname'].';dbname='.$cfg['database'].';charset=utf8mb4',
    $cfg['username'],
    $cfg['password'],
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
);

function baselineRows(PDO $db, string $sql, array $args = []): array {
    $stmt = $db->prepare($sql);
    $stmt->execute($args);
    return $stmt->fetchAll();
}
function baselineScalar(PDO $db, string $sql, array $args = []): int {
    $stmt = $db->prepare($sql);
    $stmt->execute($args);
    return (int)$stmt->fetchColumn();
}

$families = [
    'lactate' => ['table'=>'tn_device_lactate', 'expected'=>29],
    'gymware' => ['table'=>'tn_gymware_reps', 'expected'=>11],
    'eliga' => ['table'=>'tn_equipment_eliga', 'expected'=>598],
    'miccogate' => ['table'=>'tn_equipment_miccogate', 'expected'=>2],
    'vald' => ['table'=>'tn_equipment_vald', 'expected'=>8],
    'concept2' => ['table'=>'tn_equipment_concept2', 'expected'=>8],
    'wattbike' => ['table'=>'tn_equipment_wattbike', 'expected'=>3],
    'eliteform' => ['table'=>'tn_enginery_data', 'expected'=>9],
];

$result = ['mode'=>'read-only', 'families'=>[], 'total'=>0, 'assertions'=>[], 'api'=>[]];
foreach ($families as $name => $family) {
    $count = baselineScalar($db, 'SELECT COUNT(*) FROM `'.$family['table'].'`');
    $result['families'][$name] = ['table'=>$family['table'], 'count'=>$count, 'expected'=>$family['expected']];
    $result['total'] += $count;
    $result['assertions'][$name.'_count'] = $count === $family['expected'];
}
$result['assertions']['total_668'] = $result['total'] === 668;

// These are the only hardware models whose device_id the functional migration
// plans to canonicalize. Report their physical-table references before/after.
$models = ['KX21N','BC-5385CRP','ADVIA® Centaur CP','BS-380',"Clinitek\xC2\xA0Status",'NX500i'];
$hardware = baselineRows($db,
    'SELECT id,uuid,name,model_num,device_id FROM tn_equipment_hardware WHERE model_num IN ('.implode(',', array_fill(0, count($models), '?')).') OR name IN ('.implode(',', array_fill(0, count($models), '?')).') ORDER BY id',
    array_merge($models, $models)
);
$result['functional_hardware'] = $hardware;

// Mandatory API acceptance. Each family must provide list/detail/curve URLs;
// request payloads may be supplied when an endpoint needs an id or uuid.
$endpoints = json_decode((string)getenv('API_EXPECTATIONS_JSON'), true);
$cookie = (string)getenv('API_COOKIE');
if (!is_array($endpoints) || $cookie === '') {
    throw new RuntimeException('API_EXPECTATIONS_JSON and API_COOKIE are required');
}
$expectedFamilies = array_keys($families);
if (array_values(array_diff($expectedFamilies, array_keys($endpoints)))) {
    throw new RuntimeException('API expectations must cover all eight physical families');
}
foreach ($expectedFamilies as $label) {
    $spec = $endpoints[$label];
    foreach (['list_url','detail_url','curve_url'] as $required) {
        if (empty($spec[$required])) throw new RuntimeException($label.' missing '.$required);
    }
    foreach (['list','detail','curve'] as $kind) {
        $url = $spec[$kind.'_url'];
        $payload = isset($spec[$kind.'_post']) && is_array($spec[$kind.'_post'])
            ? $spec[$kind.'_post']
            : [];
        if ($kind === 'list') {
            $payload += ['page'=>1,'page_size'=>1,'start_date'=>'2026-05-01','end_date'=>'2026-08-31'];
        }
        $ch = curl_init((string)$url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER=>true,
            CURLOPT_POST=>true,
            CURLOPT_POSTFIELDS=>http_build_query($payload),
            CURLOPT_HTTPHEADER=>['Cookie: '.$cookie, 'Content-Type: application/x-www-form-urlencoded'],
            CURLOPT_TIMEOUT=>20,
        ]);
        $body = curl_exec($ch);
        $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        $json = json_decode((string)$body, true);
        $data = is_array($json) && array_key_exists('data', $json) ? $json['data'] : null;
        $total = is_array($data) && isset($data['total']) ? (int)$data['total'] : null;
        $nonEmptyData = $data !== null && $data !== '' && $data !== [];
        $ok = $status === 200 && $error === '' && is_array($json)
            && isset($json['code']) && (int)$json['code'] === 0;
        if ($kind === 'list') $ok = $ok && $total === $families[$label]['expected'];
        else $ok = $ok && $nonEmptyData;
        $result['api'][$label][$kind] = [
            'status'=>$status,
            'transport_error'=>$error,
            'json_code'=>is_array($json) && isset($json['code']) ? $json['code'] : null,
            'total'=>$total,
            'non_empty_data'=>$nonEmptyData,
            'ok'=>$ok,
        ];
    }
}

$apiFailures=[];
foreach ($result['api'] as $family => $probes) foreach ($probes as $kind => $probe) {
    if (!$probe['ok']) $apiFailures[]=$family.':'.$kind;
}
$result['ok'] = !in_array(false, $result['assertions'], true)
    && !$apiFailures;
$result['api_failures']=$apiFailures;
echo json_encode($result, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT), PHP_EOL;
exit($result['ok'] ? 0 : 1);
