# Merges an arbitrary number of MODULE.bazel.lock files.
#
# Input: an array of MODULE.bazel.lock JSON objects (as produced by `jq -s`).
# Output: a single MODULE.bazel.lock JSON object.
#
# This script assumes that all files are valid JSON and have a numeric
# "lockFileVersion" field. It will not fail on any such files, but only
# preserves information for files with a version of 10 or higher.
#
# The first file is considered to be the base when deciding which values to
# keep in case of conflicts.

# Like unique, but preserves the order of the first occurrence of each element.
def stable_unique:
  reduce .[] as $item ([]; if index($item) == null then . + [$item] else . end);

# Given an array of objects, shallowly merges the result of applying f to each
# object into a single object, with a few special properties:
# 1. Values are uniquified before merging and then merged with last-wins
#    semantics. Assuming that the first value is the base, this ensures that
#    later occurrences of the base value do not override other values. For
#    example, when this is called with B A1 A2 and A1 contains changes to a
#    field but A2 does not (compared to B), the changes in A1 will be preserved.
# 2. Object keys on the top level are sorted lexicographically after merging,
#    but are additionally split on ":". This ensures that module extension IDs,
#    which start with labels, sort as strings in the same way as they due as
#    structured objects in Bazel (that is, //python/extensions:python.bzl
#    sorts before //python/extensions/private:internal_deps.bzl).
def shallow_merge(f):
  map(f) | stable_unique | add | to_entries | sort_by(.key | split(":")) | from_entries;

(
    # Ignore all MODULE.bazel.lock files that do not have the maximum
    # lockFileVersion.
    (map(.lockFileVersion) | max) as $maxVersion
    | map(select(.lockFileVersion == $maxVersion))
    # Compute the maximum factsVersion observed across lockfiles per extension
    # ID. Missing entries default to 0.
    | (
        map(.factsVersions // {} | to_entries) | flatten
        | if length > 0 then
            group_by(.key)
            | map({key: .[0].key, value: (map(.value) | max)})
            | from_entries
          else {} end
      ) as $maxFactsVersions
    # Within each lockfile, drop facts entries whose own factsVersion does not
    # match the global maximum: those are at an outdated schema and cannot be
    # merged with newer-schema entries.
    | map(
        if has("facts") then
          (.factsVersions // {}) as $fv
          | .facts |= with_entries(
              .key as $k
              | select((($fv[$k]) // 0) == (($maxFactsVersions[$k]) // 0))
            )
        else . end
      )
    | {
        lockFileVersion: $maxVersion,
        registryFileHashes: shallow_merge(.registryFileHashes),
        selectedYankedVersions: shallow_merge(.selectedYankedVersions),
        # Group extension results by extension ID across all lockfiles with
        # shallowly merged factors map, then shallowly merge the results.
        moduleExtensions:  (map(.moduleExtensions | to_entries)
                           | flatten
                           | if length > 0 then group_by(.key) | shallow_merge({(.[0].key): shallow_merge(.value)}) else {} end),
        # Group facts by extension ID across all lockfiles (already filtered to
        # the latest factsVersion above) and shallowly merge their dicts.
        facts: (if any(has("facts")) then
                  map(.facts // {} | to_entries) | flatten |
                  if length > 0 then group_by(.key) | shallow_merge({(.[0].key): shallow_merge(.value)}) else {} end
                else null end),
        # Keep only non-zero versions, mirroring how Bazel writes the lockfile.
        factsVersions: (if any(has("factsVersions")) then
                          $maxFactsVersions | with_entries(select(.value != 0))
                        else null end),
    }
    # Filter out null values for missing top-level keys such as facts and
    # factsVersions.
    | with_entries(select(.value != null))
)? //
    # We get here if the lockfiles with the highest lockFileVersion could not be
    # processed, for example because all lockfiles have lockFileVersion < 10.
    # In this case Bazel 7.2.0+ would ignore all lockfiles, so we might as well
    # return the first lockfile for the proper "mismatched version" error
    # message.
    .[0]
