/**
 * Encode a number as varint bytes (little-endian, continuation bit).
 * @param {number} value - Value to encode
 * @param {number[]} bytes - Accumulated bytes (default empty)
 * @returns {number[]} Varint bytes
 */
const encodeVarint = (value, bytes = []) => {
  const byte = value & 0x7F
  const remaining = value >>> 7
  if (remaining === 0) {
    return [...bytes, byte]
  }
  return encodeVarint(remaining, [...bytes, byte | 0x80])
}

/**
 * Build a TAK Protocol stream frame: 0xBF, varint payload length, payload.
 * @param {string|Buffer} payload - UTF-8 payload (e.g. CoT XML)
 * @returns {Buffer} TAK stream frame buffer.
 */
export function buildTakFrame(payload) {
  const buf = Buffer.isBuffer(payload) ? payload : Buffer.from(payload, 'utf8')
  const varint = encodeVarint(buf.length)
  return Buffer.concat([Buffer.from([0xBF]), Buffer.from(varint), buf])
}

/**
 * Build CoT XML for a position update (event + point + optional contact).
 * @param {object} opts - Position options
 * @param {string} opts.uid - Entity UID
 * @param {number} opts.lat - Latitude
 * @param {number} opts.lon - Longitude
 * @param {string} [opts.callsign] - Optional callsign
 * @param {string} [opts.type] - Optional event type (default a-f-G)
 * @returns {string} CoT XML string.
 */
export function buildPositionCotXml({ uid, lat, lon, callsign, type = 'a-f-G' }) {
  const contact = callsign ? `<detail><contact callsign="${escapeXml(callsign)}"/></detail>` : ''
  return `<event uid="${escapeXml(uid)}" type="${escapeXml(type)}"><point lat="${lat}" lon="${lon}"/>${contact}</event>`
}

/**
 * Build CoT XML for auth (username/password).
 * @param {object} opts - Auth options
 * @param {string} opts.username - Username
 * @param {string} opts.password - Password
 * @returns {string} CoT XML string.
 */
export function buildAuthCotXml({ username, password }) {
  return `<event><detail><auth username="${escapeXml(username)}" password="${escapeXml(password)}"/></detail></event>`
}

function escapeXml(s) {
  return String(s)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
}
