import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { mergeVehicleActions, sampleStandardGamepad } from "../input/vehicle.ts";

function pad(over: { axes?: number[]; buttons?: Record<number, number> } = {}) {
  const buttons = Array.from({ length: 8 }, (_, index) => ({
    pressed: (over.buttons?.[index] ?? 0) > 0.5,
    value: over.buttons?.[index] ?? 0,
  }));
  return { axes: over.axes ?? [0, 0, 0, 0], buttons };
}

describe("vehicle input adapters", () => {
  it("maps a standard gamepad with a steering deadzone and analogue triggers", () => {
    const sample = sampleStandardGamepad(pad({ axes: [0.5], buttons: { 6: 0.2, 7: 0.75, 1: 1 } }));
    assert.ok(sample.actions.steering > 0 && sample.actions.steering < 0.5);
    assert.equal(sample.actions.brake, 0.2);
    assert.equal(sample.actions.throttle, 0.75);
    assert.equal(sample.actions.handbrake, true);
    assert.equal(sampleStandardGamepad(pad({ axes: [0.05] })).actions.steering, 0);
  });

  it("publishes assisted/reset buttons only on their rising edge", () => {
    const first = sampleStandardGamepad(pad({ buttons: { 2: 1, 3: 1 } }));
    assert.equal(first.actions.modeRequest, "assisted");
    assert.equal(first.actions.reset, true);
    const held = sampleStandardGamepad(pad({ buttons: { 2: 1, 3: 1 } }), first.buttons);
    assert.equal(held.actions.modeRequest, "none");
    assert.equal(held.actions.reset, false);
  });

  it("merges simultaneous adapters by strongest analogue and any safety input", () => {
    assert.deepEqual(
      mergeVehicleActions(
        { throttle: 1, steering: -0.4 },
        { brake: 0.7, steering: 0.8, handbrake: true },
      ),
      {
        throttle: 1,
        brake: 0.7,
        steering: 0.8,
        handbrake: true,
        modeRequest: "none",
        reset: false,
      },
    );
  });
});
