/**
 * Connection token utilities for RemoteIngress edge connections.
 * A token is a base64url-encoded compact JSON object carrying hub connection details.
 */

export interface IConnectionTokenData {
  hubHost: string;
  hubPort: number;
  edgeId: string;
  secret: string;
}

/**
 * Encode connection data into a single opaque token string (base64url).
 */
export function encodeConnectionToken(data: IConnectionTokenData): string {
  const compact = JSON.stringify({
    h: data.hubHost,
    p: data.hubPort,
    e: data.edgeId,
    s: data.secret,
  });
  // base64url: standard base64 with + → -, / → _, trailing = stripped
  return Buffer.from(compact, 'utf-8')
    .toString('base64')
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
}

/**
 * Decode a connection token back into its constituent fields.
 * Throws on malformed or incomplete tokens.
 */
export function decodeConnectionToken(token: string): IConnectionTokenData {
  let parsed: { h?: unknown; p?: unknown; e?: unknown; s?: unknown };
  try {
    // Restore standard base64 from base64url
    let base64 = token.replace(/-/g, '+').replace(/_/g, '/');
    // Re-add padding
    const remainder = base64.length % 4;
    if (remainder === 2) base64 += '==';
    else if (remainder === 3) base64 += '=';

    const json = Buffer.from(base64, 'base64').toString('utf-8');
    parsed = JSON.parse(json);
  } catch {
    throw new Error('Invalid connection token');
  }

  if (
    typeof parsed.h !== 'string' ||
    typeof parsed.p !== 'number' ||
    typeof parsed.e !== 'string' ||
    typeof parsed.s !== 'string'
  ) {
    throw new Error('Invalid connection token: missing required fields');
  }

  return {
    hubHost: parsed.h,
    hubPort: parsed.p,
    edgeId: parsed.e,
    secret: parsed.s,
  };
}
