<?php
declare(strict_types=1);

$phase = (string)($argv[1] ?? '');
$lane = (string)($argv[2] ?? '');
$marker = (string)($argv[3] ?? '');
if (!in_array($phase, ['--run', '--audit'], true) || !in_array($lane, ['B', 'C'], true)
    || !preg_match('/^CDXHWLOG[A-F0-9]{8}$/D', $marker)
    || ($phase === '--run' && getenv('CDX_HWLOG_RUN') !== 'ONE_OWNED_DB_LOG_V1')) {
    fwrite(STDERR, "DENIED business_http=0 business_dml=0\n"); exit(78);
}
if ($lane === 'B') {
    $config = include '/tmp/zhct-http-store-mysql.dQTTBP/application/config/local/database.php';
    if (!is_array($config) || ($config['database'] ?? '') !== 'zhct'
        || hash('sha256', (string)($config['hostname'] ?? ''))
            !== '47e8be48b0cfd56dcdb9d9d426e6637b245f340b4efad4cd2f084ec5851ecc8e') {
        throw new RuntimeException('B code-local MySQL identity drift');
    }
    $db = new PDO('mysql:host=' . $config['hostname'] . ';port=3306;dbname=zhct;charset=utf8',
        $config['username'], $config['password'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER]);
    $port = 18081;
} else {
    if (getenv('POC_DIALECT') !== 'dm' || getenv('POC_HOST') !== '127.0.0.1'
        || getenv('POC_PORT') !== '5237' || getenv('POC_SCHEMA') !== 'ZHCT_APP'
        || getenv('POC_USER') !== 'ZHCT_APP') {
        throw new RuntimeException('C isolated Store DM identity drift');
    }
    $db = new PDO('dm:host=127.0.0.1;port=5237;schema=ZHCT_APP',
        getenv('POC_USER'), getenv('POC_PASSWORD'),
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER]);
    if ($db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn() !== 'ZHCT_APP') {
        throw new RuntimeException('C schema drift');
    }
    $port = 18080;
}
$ownedRows = static function () use ($db, $marker): array {
    $query = $db->prepare('SELECT id,event,event_date,event_time,event_code,event_msg,'
        . 'machine_code,user_face_url,dishes_weight,similarity'
        . ' FROM ydy_hardware_log WHERE event_msg=? AND machine_code=?');
    $query->execute([$marker, $marker]);
    return array_map(static function (array $row): array {
        return array_change_key_case($row, CASE_LOWER);
    }, $query->fetchAll(PDO::FETCH_ASSOC));
};
$ownedAttendance = static function () use ($db, $marker): array {
    $query = $db->prepare('SELECT id,staff_uuid,face_img_url,daka_date,daka_time,'
        . 'daka_address,baidu_code,status FROM ydy_sign_daka'
        . ' WHERE daka_address=? AND baidu_code=?');
    $query->execute([$marker, $marker]);
    return array_map(static function (array $row): array {
        return array_change_key_case($row, CASE_LOWER);
    }, $query->fetchAll(PDO::FETCH_ASSOC));
};
$before = $ownedRows();
$attendanceBefore = $ownedAttendance();
if ($phase === '--audit') {
    echo json_encode(['lane' => $lane, 'phase' => 'audit', 'marker' => $marker,
        'owned_log_count' => count($before),
        'owned_attendance_count' => count($attendanceBefore), 'business_http' => 0,
        'business_dml' => 0]), PHP_EOL;
    exit($before || $attendanceBefore ? 2 : 0);
}
if ($before || $attendanceBefore) throw new RuntimeException('owned marker already exists');
$staffSql = 'SELECT uuid FROM ydy_staff WHERE is_show=1 AND status=1 ORDER BY id DESC'
    . ($lane === 'B' ? ' LIMIT 1' : ' FETCH FIRST 1 ROWS ONLY');
$staffUuid = $db->query($staffSql)->fetchColumn();
if (!is_string($staffUuid) || $staffUuid === '') {
    throw new RuntimeException('no active original staff for attendance');
}
$http = static function (string $path, array $form) use ($port): array {
    if (!in_array($path, ['/p/api/hardware_log', '/p/api/sign_daka'], true)) {
        throw new RuntimeException('unsupported fixed hardware endpoint');
    }
    $ctx = stream_context_create(['http' => [
        'method' => 'POST', 'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
        'content' => http_build_query($form, '', '&', PHP_QUERY_RFC3986),
        'ignore_errors' => true, 'timeout' => 15, 'follow_location' => 0,
    ]]);
    $handle = @fopen('http://127.0.0.1:' . $port . $path, 'rb', false, $ctx);
    if (!is_resource($handle)) throw new RuntimeException('isolated Store HTTP unavailable');
    $raw = stream_get_contents($handle, 131073);
    fclose($handle);
    if (!is_string($raw) || strlen($raw) > 131072) throw new RuntimeException('hardware log response cap');
    $body = json_decode($raw, true);
    if (!is_array($body) || (int)($body['code'] ?? -1) !== 0) {
        throw new RuntimeException('hardware log HTTP business failure code='
            . (string)($body['code'] ?? 'nonjson')
            . ' message=' . substr((string)($body['message'] ?? ''), 0, 100));
    }
    return $body;
};
$eventTime = date('Y-m-d H:i:s');
$error = null;
$result = [];
try {
    $body = $http('/p/api/hardware_log', [
        'event' => 2, 'event_time' => $eventTime,
        'event_code' => 1, 'event_msg' => $marker,
        'machine_code' => $marker, 'machine_type' => 4,
        'dishes_weight' => '12.34', 'similarity' => '0.85',
    ]);
    $rows = $ownedRows();
    if (count($rows) !== 1) throw new RuntimeException('hardware log exact own insert count differs');
    $row = $rows[0];
    if ((int)$row['event'] !== 2 || (int)$row['event_code'] !== 1
        || (string)$row['event_msg'] !== $marker
        || (string)$row['machine_code'] !== $marker
        || substr((string)$row['event_time'], 0, 19) !== $eventTime
        || substr((string)$row['event_date'], 0, 10) !== substr($eventTime, 0, 10)
        || abs((float)$row['dishes_weight'] - 12.34) > 0.00001
        || abs((float)$row['similarity'] - 0.85) > 0.00001
        || (string)$row['user_face_url'] !== '') {
        throw new RuntimeException('hardware log form-to-original-row mismatch');
    }
    if (!array_key_exists('data', $body) || $body['data'] !== null) {
        throw new RuntimeException('hardware log response data contract differs');
    }
    $result = ['http_business_ok' => 1, 'event_fields_source_equal' => true,
        'date_and_float_input_source_equal' => true,
        'response_data_null' => true];
    $attendance = $http('/p/api/sign_daka', [
        'staff_uuid' => $staffUuid, 'daka_time' => $eventTime,
        'daka_address' => $marker, 'baidu_code' => $marker,
    ]);
    $attendanceRows = $ownedAttendance();
    if (count($attendanceRows) !== 1) throw new RuntimeException('own attendance insert count differs');
    $attendanceRow = $attendanceRows[0];
    if ((string)$attendanceRow['staff_uuid'] !== $staffUuid
        || (string)$attendanceRow['daka_address'] !== $marker
        || (string)$attendanceRow['baidu_code'] !== $marker
        || substr((string)$attendanceRow['daka_time'], 0, 19) !== $eventTime
        || substr((string)$attendanceRow['daka_date'], 0, 10) !== substr($eventTime, 0, 10)
        || (string)$attendanceRow['face_img_url'] !== ''
        || (int)$attendanceRow['status'] !== 1
        || !array_key_exists('data', $attendance) || $attendance['data'] !== null) {
        throw new RuntimeException('attendance form-to-original-row or response differs');
    }
    $result['http_business_ok'] = 2;
    $result['attendance_source_equal'] = true;
} catch (Throwable $caught) {
    $error = $caught;
} finally {
    foreach ($ownedAttendance() as $ownedRow) {
        $delete = $db->prepare('DELETE FROM ydy_sign_daka'
            . ' WHERE id=? AND daka_address=? AND baidu_code=?');
        $delete->execute([(int)$ownedRow['id'], $marker, $marker]);
    }
    foreach ($ownedRows() as $ownedRow) {
        $delete = $db->prepare('DELETE FROM ydy_hardware_log'
            . ' WHERE id=? AND event_msg=? AND machine_code=?');
        $delete->execute([(int)$ownedRow['id'], $marker, $marker]);
    }
}
if ($ownedRows() || $ownedAttendance()) throw new RuntimeException('own hardware rows cleanup failed');
if ($error !== null) throw $error;
echo json_encode(['lane' => $lane, 'marker' => $marker] + $result + [
    'owned_cleanup_zero' => true,
    'business_dml' => 'one-owned-hardware-log-and-one-attendance-insert-then-delete',
    'face_file_oss' => 0,
], JSON_UNESCAPED_SLASHES), PHP_EOL;
