/**
 * Fill a contiguous span of untranslated slots in a locale file.
 *
 * Locale files are positional arrays of ~450 entries, so re-sending the whole
 * file just to add a handful of strings is wasteful and error-prone. This
 * patches only the given index ranges, and refuses to overwrite a slot that
 * already holds a translation.
 *
 *   node tools/i18n-patch.mjs <locale> <ranges> <json-array-file>
 *
 * `ranges` is comma-separated, e.g. "3-28,83-141". The JSON file holds an
 * array of strings whose length must equal the total span.
 */
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'

const SRC_DIR = path.resolve(import.meta.dirname, '..', 'languages', 'src')

function parseRanges(spec) {
  const indexes = []

  for (const part of spec.split(',')) {
    const [from, to] = part.split('-').map(Number)
    // A bare index ("5") has no `to`; `Number.isNaN(undefined)` is false, so
    // check for undefined explicitly or the loop never runs.
    const last = to === undefined || Number.isNaN(to) ? from : to
    for (let i = from; i <= last; i += 1) indexes.push(i)
  }

  return indexes
}

const [locale, rangeSpec, valuesFile] = process.argv.slice(2)

if (!locale || !rangeSpec || !valuesFile) {
  console.error('usage: node tools/i18n-patch.mjs <locale> <ranges> <json-array-file>')
  process.exit(1)
}

const localeFile = path.join(SRC_DIR, `${locale}.json`)
const entries = JSON.parse(fs.readFileSync(localeFile, 'utf8'))
const msgids = JSON.parse(fs.readFileSync(path.join(SRC_DIR, 'msgids.json'), 'utf8'))
const values = JSON.parse(fs.readFileSync(valuesFile, 'utf8'))
const indexes = parseRanges(rangeSpec)

if (values.length !== indexes.length) {
  console.error(`${locale}: got ${values.length} values for ${indexes.length} slots`)
  process.exit(1)
}

let written = 0
const collisions = []

indexes.forEach((index, i) => {
  const existing = entries[index]
  const filled = Array.isArray(existing) ? existing.some(Boolean) : Boolean(existing)

  if (filled) {
    collisions.push(`${index} (${msgids[index]?.id.slice(0, 40)})`)
    return
  }

  entries[index] = values[i]
  written += 1
})

fs.writeFileSync(localeFile, `${JSON.stringify(entries, null, 2)}\n`)

console.log(`  ${locale}: filled ${written}/${indexes.length}`)
if (collisions.length) {
  console.log(`    skipped ${collisions.length} already-translated: ${collisions.slice(0, 3).join(', ')}`)
}
