/**
 * Client/server version compatibility, mirroring
 * crates/cambium-core/src/version.rs and CambiumServer/server.py's VERSION
 * block — all three must agree.
 *
 * Compatibility is decided on the MAJOR component alone: a 0.x client talks to
 * any 0.x server and is refused by a 1.x one, and vice versa. Minor/patch skew
 * inside one major line stays allowed, so a server can ship a fix without
 * forcing every user to upgrade in lockstep.
 *
 * This lives in its own module rather than in api/client.js because
 * platform.js's `apiFetch` needs it too, and api/client.js imports
 * platform.js — putting it there would make that a cycle.
 */

/** Injected from package.json by vite (see vite.config.js), so a release
 *  bumps one number rather than one per file. */
export const CLIENT_VERSION = __CAMBIUM_VERSION__;

/** Header every request carries so the server can apply the rule from its
 *  side. Attached centrally in platform.js's `apiFetch`. */
export const CLIENT_VERSION_HEADER = 'X-Cambium-Client';

/** MAJOR of a `major.minor.patch` string, or null when it isn't readable as
 *  one. Unparseable counts as incompatible rather than assumed-current. */
export function majorOf(version) {
  // Digits only, like Rust's `str::parse::<u64>` — "1abc" and "v1" are not
  // versions this client claims to understand.
  const head = String(version ?? '').trim().split('.')[0];
  return /^\d+$/.test(head) ? Number.parseInt(head, 10) : null;
}

/** True when a client and server on these versions may talk to each other. */
export function isCompatible(clientVersion, serverVersion) {
  const client = majorOf(clientVersion);
  const server = majorOf(serverVersion);
  return client !== null && server !== null && client === server;
}

/** User-facing explanation for a refused connection — names which side is
 *  behind, because "incompatible" alone leaves the user with nothing to do. */
export function incompatibilityMessage(serverVersion) {
  const client = majorOf(CLIENT_VERSION);
  const server = majorOf(serverVersion);
  if (client === null || server === null) {
    return `This server reported an unrecognized version (${serverVersion}); this client is ${CLIENT_VERSION}.`;
  }
  return server > client
    ? `This server runs Cambium ${serverVersion}, which is newer than this client (${CLIENT_VERSION}). Update the client to connect.`
    : `This server runs Cambium ${serverVersion}, which is older than this client (${CLIENT_VERSION}). The server needs to be updated to accept this client.`;
}
