// `Core` is the typed TypeScript view of the Galaxy compute boundary
// (`ui/core` Go module compiled to WASM/native). It only carries
// canonical-bytes serialization and signature verification — no
// network I/O, no key storage, no signing private keys. Real Ed25519
// signing happens in a platform-specific `Signer` (Phase 6 introduces
// WebCrypto for the web target).
//
// All byte fields are `Uint8Array`. Timestamps are `bigint` to keep
// nanosecond-resolution-friendly headroom and to mirror the v2
// Protobuf-ES `int64 → bigint` mapping used by the generated stubs.

export interface RequestSigningFields {
	protocolVersion: string;
	deviceSessionId: string;
	messageType: string;
	timestampMs: bigint;
	requestId: string;
	payloadHash: Uint8Array;
}

export interface ResponseSigningFields {
	protocolVersion: string;
	requestId: string;
	timestampMs: bigint;
	resultCode: string;
	payloadHash: Uint8Array;
}

export interface EventSigningFields {
	eventType: string;
	eventId: string;
	timestampMs: bigint;
	requestId: string;
	traceId: string;
	payloadHash: Uint8Array;
}

export interface DriveEffectiveInput {
	drive: number;
	driveTech: number;
}

export interface ShipBlocksInput {
	drive: number;
	weapons: number;
	armament: number;
	shields: number;
	cargo: number;
}

export interface WeaponsBlockInput {
	weapons: number;
	armament: number;
}

export interface FullMassInput {
	emptyMass: number;
	carryingMass: number;
}

export interface SpeedInput {
	driveEffective: number;
	fullMass: number;
}

export interface CargoCapacityInput {
	cargo: number;
	cargoTech: number;
}

export interface CarryingMassInput {
	load: number;
	cargoTech: number;
}

export interface BlockUpgradeCostInput {
	blockMass: number;
	currentTech: number;
	targetTech: number;
}

export interface Core {
	/**
	 * signRequest returns the canonical signing input bytes for a v1
	 * request envelope. Callers feed the result into a platform `Signer`
	 * (e.g. WebCrypto) to produce the actual Ed25519 signature.
	 */
	signRequest(fields: RequestSigningFields): Uint8Array;

	/**
	 * verifyResponse authenticates a server response signature against
	 * the canonical v1 response signing input.
	 */
	verifyResponse(
		publicKey: Uint8Array,
		signature: Uint8Array,
		fields: ResponseSigningFields,
	): boolean;

	/**
	 * verifyEvent authenticates a push-event signature against the
	 * canonical v1 event signing input.
	 */
	verifyEvent(
		publicKey: Uint8Array,
		signature: Uint8Array,
		fields: EventSigningFields,
	): boolean;

	/**
	 * verifyPayloadHash returns true when payloadHash is the raw 32-byte
	 * SHA-256 digest of payloadBytes.
	 */
	verifyPayloadHash(
		payloadBytes: Uint8Array,
		payloadHash: Uint8Array,
	): boolean;

	/**
	 * driveEffective wraps `pkg/calc/ship.go.DriveEffective`: effective
	 * drive power = ship drive block × player drive tech.
	 */
	driveEffective(input: DriveEffectiveInput): number;

	/**
	 * emptyMass wraps `pkg/calc/ship.go.EmptyMass`: mass of the ship
	 * with empty holds. Returns null when the upstream validator
	 * rejects the weapons/armament pair (one zero and the other
	 * non-zero).
	 */
	emptyMass(input: ShipBlocksInput): number | null;

	/**
	 * weaponsBlockMass wraps `pkg/calc/ship.go.WeaponsBlockMass`: mass
	 * of the weapons sub-block. Returns null on the same invalid
	 * pairing as emptyMass.
	 */
	weaponsBlockMass(input: WeaponsBlockInput): number | null;

	/**
	 * fullMass wraps `pkg/calc/ship.go.FullMass`: empty mass plus the
	 * mass of the carried cargo.
	 */
	fullMass(input: FullMassInput): number;

	/**
	 * speed wraps `pkg/calc/ship.go.Speed`: light-years per turn,
	 * driveEffective × 20 / fullMass; zero when fullMass ≤ 0.
	 */
	speed(input: SpeedInput): number;

	/**
	 * cargoCapacity wraps `pkg/calc/ship.go.CargoCapacity`: hold
	 * capacity of one ship in cargo units, scaled by the player's
	 * cargo tech.
	 */
	cargoCapacity(input: CargoCapacityInput): number;

	/**
	 * carryingMass wraps `pkg/calc/ship.go.CarryingMass`: mass of a
	 * payload of `load` cargo units at the player's cargo tech. Used
	 * by the ship-class designer to derive full-load mass from
	 * cargoCapacity.
	 */
	carryingMass(input: CarryingMassInput): number;

	/**
	 * blockUpgradeCost wraps `pkg/calc/ship.go.BlockUpgradeCost`:
	 * production cost of moving one ship block from currentTech to
	 * targetTech, scaled by the block mass and a constant 10. Returns
	 * 0 when blockMass is zero or targetTech is not above currentTech.
	 * Phase 20's ship-group inspector calls this once per block
	 * (drive, weapons, shields, cargo) to render the modernize cost
	 * preview.
	 */
	blockUpgradeCost(input: BlockUpgradeCostInput): number;
}

export type CoreLoader = () => Promise<Core>;

import { loadWasmCore } from "./wasm";

/**
 * loadCore resolves the Core implementation appropriate for the current
 * build target. Phase 5 ships only the WASM adapter; later phases plug
 * `WailsCore` and `CapacitorCore` here behind a build-time selector.
 */
export const loadCore: CoreLoader = loadWasmCore;
