/** Strict runtime boundary for the JSON-only office screen signaling protocol. */

import {
  MAX_SCREEN_SHARE_PARTICIPANTS,
  SCREEN_SHARE_SIGNALING_PROTOCOL_VERSION,
  type ScreenShareAccessGrant,
  type ScreenShareBinding,
  type ScreenShareClientMessage,
  type ScreenShareCredential,
  type ScreenShareParticipant,
  type ScreenSharePeerMessage,
  type ScreenShareServerMessage,
  type ScreenShareSignalPayload,
  type ScreenShareStreamCursor,
  type ScreenShareValidationResult,
} from "./signalingTypes.ts";

const MAX_ID = 256;
const MAX_TOKEN = 512;
const MAX_SDP = 24 * 1024;
const MAX_CANDIDATE = 4 * 1024;

type RecordValue = Record<string, unknown>;

function plain(value: unknown): value is RecordValue {
  if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
  const prototype = Object.getPrototypeOf(value);
  return prototype === Object.prototype;
}

function exact(value: unknown, keys: readonly string[]): value is RecordValue {
  if (!plain(value)) return false;
  const actual = Object.keys(value).sort();
  const expected = [...keys].sort();
  return actual.length === expected.length && actual.every((key, index) => key === expected[index]);
}

function id(value: unknown, maximum = MAX_ID): value is string {
  return typeof value === "string" && value.length > 0 && value.length <= maximum;
}

function sequence(value: unknown): value is number {
  return Number.isSafeInteger(value) && (value as number) >= 0;
}

function timestamp(value: unknown): value is number {
  return Number.isSafeInteger(value) && (value as number) >= 0;
}

function envelope(value: RecordValue): boolean {
  return value.protocolVersion === SCREEN_SHARE_SIGNALING_PROTOCOL_VERSION &&
    sequence(value.sequence) && timestamp(value.timestampMs);
}

function binding(value: unknown): value is ScreenShareBinding {
  return exact(value, ["officeId", "levelId", "roomId", "screenId"]) &&
    id(value.officeId, 128) && id(value.levelId, 128) &&
    (value.roomId === null || id(value.roomId, 128)) && id(value.screenId, 128);
}

function credential(value: unknown): value is ScreenShareCredential {
  return exact(value, ["sessionId", "participantId", "role", "grantToken"]) &&
    id(value.sessionId) && id(value.participantId) &&
    (value.role === "presenter" || value.role === "viewer") && id(value.grantToken, MAX_TOKEN);
}

function participant(value: unknown): value is ScreenShareParticipant {
  return exact(value, ["participantId", "role"]) && id(value.participantId) &&
    (value.role === "presenter" || value.role === "viewer");
}

function participants(value: unknown): value is readonly ScreenShareParticipant[] {
  if (!Array.isArray(value) || value.length > MAX_SCREEN_SHARE_PARTICIPANTS - 1 || !value.every(participant)) return false;
  const ids = value.map((item) => item.participantId);
  return new Set(ids).size === ids.length && value.filter((item) => item.role === "presenter").length <= 1;
}

function accessGrant(value: unknown): value is ScreenShareAccessGrant {
  return exact(value, ["credential", "issuedAtMs", "expiresAtMs"]) && credential(value.credential) &&
    timestamp(value.issuedAtMs) && timestamp(value.expiresAtMs) && value.expiresAtMs > value.issuedAtMs;
}

function signal(value: unknown): value is ScreenShareSignalPayload {
  if (!plain(value)) return false;
  if (value.kind === "sdp") {
    return exact(value, ["kind", "descriptionType", "sdp"]) &&
      (value.descriptionType === "offer" || value.descriptionType === "answer") &&
      id(value.sdp, MAX_SDP);
  }
  if (value.kind === "ice-candidate") {
    return exact(value, ["kind", "candidate", "sdpMid", "sdpMLineIndex", "usernameFragment"]) &&
      typeof value.candidate === "string" && value.candidate.length <= MAX_CANDIDATE &&
      (value.sdpMid === null || id(value.sdpMid, 256)) &&
      (value.sdpMLineIndex === null || (Number.isInteger(value.sdpMLineIndex) && (value.sdpMLineIndex as number) >= 0 && (value.sdpMLineIndex as number) <= 65_535)) &&
      (value.usernameFragment === null || id(value.usernameFragment, 256));
  }
  return value.kind === "ice-complete" && exact(value, ["kind"]);
}

function requested(value: RecordValue): boolean {
  return envelope(value) && id(value.requestId);
}

export function parseScreenShareClientMessage(value: unknown): ScreenShareValidationResult<ScreenShareClientMessage> {
  if (!plain(value) || !envelope(value) || typeof value.type !== "string") return failure("invalid client envelope");
  switch (value.type) {
    case "screen-share-create-request":
      if (exact(value, ["type", "protocolVersion", "sequence", "timestampMs", "requestId", "binding", "role"]) &&
          requested(value) && binding(value.binding) && value.role === "presenter") return success(value as unknown as ScreenShareClientMessage);
      break;
    case "screen-share-join-request":
      if (exact(value, ["type", "protocolVersion", "sequence", "timestampMs", "requestId", "binding", "role", "viewerOptIn"]) &&
          requested(value) && binding(value.binding) && value.role === "viewer" && value.viewerOptIn === true) return success(value as unknown as ScreenShareClientMessage);
      break;
    case "screen-share-resume-request":
      if (exact(value, ["type", "protocolVersion", "sequence", "timestampMs", "requestId", "binding", "credential", "lastReceivedSequence"]) &&
          requested(value) && binding(value.binding) && credential(value.credential) && sequence(value.lastReceivedSequence)) return success(value as unknown as ScreenShareClientMessage);
      break;
    case "screen-share-signal-request":
      if (exact(value, ["type", "protocolVersion", "sequence", "timestampMs", "binding", "credential", "targetParticipantId", "signal"]) &&
          binding(value.binding) && credential(value.credential) && id(value.targetParticipantId) && signal(value.signal) &&
          value.targetParticipantId !== value.credential.participantId) return success(value as unknown as ScreenShareClientMessage);
      break;
    case "screen-share-stop-request":
      if (exact(value, ["type", "protocolVersion", "sequence", "timestampMs", "requestId", "binding", "credential", "reason"]) &&
          requested(value) && binding(value.binding) && credential(value.credential) && value.credential.role === "presenter" &&
          (value.reason === "presenter-stopped" || value.reason === "capture-ended")) return success(value as unknown as ScreenShareClientMessage);
      break;
    case "screen-share-revoke-request":
      if (exact(value, ["type", "protocolVersion", "sequence", "timestampMs", "requestId", "binding", "credential", "scope", "targetParticipantId", "reason"]) &&
          requested(value) && binding(value.binding) && credential(value.credential) &&
          (value.scope === "session" || value.scope === "participant") &&
          (value.targetParticipantId === null || id(value.targetParticipantId)) &&
          (value.reason === "viewer-left" || value.reason === "presenter-removed-viewer" || value.reason === "moderator-action") &&
          ((value.scope === "session" && value.targetParticipantId === null) || (value.scope === "participant" && id(value.targetParticipantId)))) {
        return success(value as unknown as ScreenShareClientMessage);
      }
      break;
  }
  return failure("invalid client message");
}

function grantEnvelope(value: RecordValue, resume: boolean): boolean {
  const keys = ["type", "protocolVersion", "sequence", "timestampMs", "requestId", "binding", "grant", "nextClientSequence", "participants"];
  if (resume) keys.push("continuous");
  return exact(value, keys) && requested(value) && binding(value.binding) && accessGrant(value.grant) &&
    sequence(value.nextClientSequence) && participants(value.participants) && (!resume || typeof value.continuous === "boolean");
}

export function parseScreenShareServerMessage(value: unknown): ScreenShareValidationResult<ScreenShareServerMessage> {
  if (!plain(value) || !envelope(value) || typeof value.type !== "string") return failure("invalid server envelope");
  switch (value.type) {
    case "screen-share-create-grant":
      if (grantEnvelope(value, false) && (value.grant as ScreenShareAccessGrant).credential.role === "presenter") return success(value as unknown as ScreenShareServerMessage);
      break;
    case "screen-share-join-grant":
      if (grantEnvelope(value, false) && (value.grant as ScreenShareAccessGrant).credential.role === "viewer") return success(value as unknown as ScreenShareServerMessage);
      break;
    case "screen-share-resume-grant":
      if (grantEnvelope(value, true)) return success(value as unknown as ScreenShareServerMessage);
      break;
    case "screen-share-participants":
      if (exact(value, ["type", "protocolVersion", "sequence", "timestampMs", "sessionId", "binding", "participants", "leaseExpiresAtMs"]) &&
          id(value.sessionId) && binding(value.binding) && participants(value.participants) &&
          timestamp(value.timestampMs) && timestamp(value.leaseExpiresAtMs) &&
          (value.leaseExpiresAtMs as number) > (value.timestampMs as number)) return success(value as unknown as ScreenShareServerMessage);
      break;
    case "screen-share-signal-relay":
      if (exact(value, ["type", "protocolVersion", "sequence", "timestampMs", "sessionId", "binding", "fromParticipantId", "targetParticipantId", "signal"]) &&
          id(value.sessionId) && binding(value.binding) && id(value.fromParticipantId) && id(value.targetParticipantId) &&
          value.fromParticipantId !== value.targetParticipantId && signal(value.signal)) return success(value as unknown as ScreenShareServerMessage);
      break;
    case "screen-share-stopped":
      if (exact(value, ["type", "protocolVersion", "sequence", "timestampMs", "sessionId", "binding", "reason"]) &&
          id(value.sessionId) && binding(value.binding) &&
          (value.reason === "presenter-stopped" || value.reason === "capture-ended" || value.reason === "grant-expired" || value.reason === "server-shutdown")) {
        return success(value as unknown as ScreenShareServerMessage);
      }
      break;
    case "screen-share-revoked":
      if (exact(value, ["type", "protocolVersion", "sequence", "timestampMs", "sessionId", "binding", "scope", "targetParticipantId", "reason", "reconnectAllowed"]) &&
          id(value.sessionId) && binding(value.binding) && (value.scope === "session" || value.scope === "participant") &&
          (value.targetParticipantId === null || id(value.targetParticipantId)) && typeof value.reconnectAllowed === "boolean" &&
          ["viewer-left", "presenter-removed-viewer", "moderator-action", "authorization-revoked", "membership-revoked", "protocol-violation", "session-replaced"].includes(String(value.reason)) &&
          ((value.scope === "session" && value.targetParticipantId === null) || (value.scope === "participant" && id(value.targetParticipantId)))) {
        return success(value as unknown as ScreenShareServerMessage);
      }
      break;
  }
  return failure("invalid server message");
}

export function isScreenShareGrantActive(grant: ScreenShareAccessGrant, nowMs: number): boolean {
  return accessGrant(grant) && timestamp(nowMs) && nowMs >= grant.issuedAtMs && nowMs < grant.expiresAtMs;
}

export function advanceScreenShareStreamCursor(
  cursor: ScreenShareStreamCursor | null,
  message: ScreenSharePeerMessage,
): ScreenShareValidationResult<ScreenShareStreamCursor> {
  const parsed = parseScreenShareServerMessage(message);
  if (!parsed.ok || !["screen-share-participants", "screen-share-signal-relay", "screen-share-stopped", "screen-share-revoked"].includes(parsed.value.type)) {
    return failure("invalid peer message");
  }
  if (cursor && (cursor.sessionId !== message.sessionId || message.sequence <= cursor.sequence || message.timestampMs < cursor.timestampMs)) {
    return failure("stale or foreign stream message");
  }
  return success({ sessionId: message.sessionId, sequence: message.sequence, timestampMs: message.timestampMs });
}

function success<T>(value: T): ScreenShareValidationResult<T> { return { ok: true, value }; }
function failure<T>(detail: string): ScreenShareValidationResult<T> { return { ok: false, error: `screen share: ${detail}` }; }
