<?php

namespace Modules\LabCore\Entities\Contracts;

/**
 * Contract every analyzer-vendor module implements and registers with the
 * LabCore DriverRegistry. The vendor module owns the protocol-specific
 * knowledge; LabCore owns storage, UI, the agent-sync API and VetClinic
 * linkage.
 *
 * @see \Modules\LabCore\Entities\Services\DriverRegistry
 */
interface LabDeviceDriver
{
    /**
     * Machine vendor key. Stored on lab_* rows and used as the registry key.
     * e.g. 'nx600', 'abaxis', 'idexx'.
     */
    public function vendor(): string;

    /**
     * Human-readable vendor label, e.g. 'NX600 Analyzer'.
     */
    public function label(): string;

    /**
     * Supported analyzer models, e.g. ['VetScan VS2', 'VetScan HM5'].
     */
    public function models(): array;

    /**
     * Communication protocols this driver speaks, e.g. ['astm-e1394']
     * or ['nx600-type-1', 'nx600-type-A', 'nx600-hl7'].
     */
    public function commProtocols(): array;

    /**
     * Connection types this vendor's devices support — subset of
     * config('labcore.connection_types') keys: tcp, serial, serial2eth.
     */
    public function connectionTypes(): array;

    /**
     * Seed rows for lab_analyte_map — the vendor's analyte catalog.
     * Each row: ['analyte_code', 'canonical_name', 'display_name', 'unit',
     * 'species', 'ref_lower', 'ref_upper', 'category'].
     *
     * @return array<int,array<string,mixed>>
     */
    public function defaultAnalyteMap(): array;

    /**
     * Parse a raw, transport-stripped device message into the vendor's own
     * structured representation. Returns null when the message is not a result
     * payload (e.g. a worklist query) or cannot be parsed.
     *
     * @param  string $raw      Assembled message text/bytes (E1381/transport
     *                          framing already removed by the LabBridge Agent).
     * @param  array  $context  Hints: comm_protocol, device_id, business_id...
     */
    public function parse(string $raw, array $context = []): ?array;

    /**
     * Normalize a vendor-parsed payload into the canonical LabCore shape.
     *
     * @param  array $parsed  Vendor-specific parsed result structure (the
     *                        output of {@see parse()}).
     * @return array{session: array<string,mixed>, results: array<int,array<string,mixed>>}
     *         'session' = lab_test_sessions field set,
     *         'results' = list of lab_test_results field sets.
     */
    public function normalize(array $parsed): array;
}
