#!/usr/bin/env bash

: <<'DOC'
Section-aware TOML read/write primitives.

Not a full TOML parser — handles the flat key-value patterns common in
Cargo.toml and similar configuration files. Operates on files directly
with atomic temp-file-then-mv writes.
DOC

# ── Core functions ────────────────────────────────────────────────────

: <<'DOC'
Reads a value from a [section] by key name.
Returns the raw value (unquoted for strings, as-is for booleans/numbers).
Returns empty string if not found.

  toml_get "Cargo.toml" "package" "version"
  toml_get "Cargo.toml" "workspace.package" "edition"
DOC
function toml_get() {
  local file="$1" section="$2" key="$3"
  local in_section=false

  while IFS= read -r line; do
    if [[ "$line" == "[$section]" ]]; then
      in_section=true
    elif [[ "$line" == "["* ]]; then
      $in_section && return
      in_section=false
    elif $in_section && [[ "$line" =~ ^[[:space:]]*${key}[[:space:]]*= ]]; then
      local value="${line#*= }"
      value="${value#\"}"
      value="${value%\"}"
      echo "$value"
      return
    fi
  done < "$file"
}

: <<'DOC'
Sets a key in a section. Updates if exists, appends before the next section
header if not. Creates the section if it doesn't exist.

  toml_set "Cargo.toml" "package" "version" '"1.2.3"'
DOC
function toml_set() {
  local file="$1" section="$2" key="$3" value="$4"

  if ! toml_has_key "$file" "$section" "$key"; then
    __toml__append_to_section "$file" "$section" "$key" "$value"
    return
  fi

  local temp_file="${file}.tmp"
  local in_section=false replaced=false

  while IFS= read -r line; do
    if [[ "$line" == "[$section]" ]]; then
      in_section=true
    elif [[ "$line" == "["* ]]; then
      in_section=false
    fi

    if $in_section && ! $replaced && [[ "$line" =~ ^[[:space:]]*${key}[[:space:]]*= ]]; then
      echo "${key} = ${value}"
      replaced=true
    else
      echo "$line"
    fi
  done < "$file" > "$temp_file"
  mv "$temp_file" "$file"
}

: <<'DOC'
Returns 0 if key exists in section, 1 otherwise.

  toml_has_key "Cargo.toml" "package" "version"
DOC
function toml_has_key() {
  local file="$1" section="$2" key="$3"
  local in_section=false

  while IFS= read -r line; do
    if [[ "$line" == "[$section]" ]]; then
      in_section=true
    elif [[ "$line" == "["* ]]; then
      $in_section && return 1
      in_section=false
    elif $in_section && [[ "$line" =~ ^[[:space:]]*${key}[[:space:]]*= ]]; then
      return 0
    fi
  done < "$file"

  return 1
}

: <<'DOC'
Targeted replacement of a specific value for a key within a section.
Only replaces if the current value matches $old.

  toml_replace "Cargo.toml" "workspace.package" "version" "1.0.0" "2.0.0"
DOC
function toml_replace() {
  local file="$1" section="$2" key="$3" old="$4" new="$5"
  local temp_file="${file}.tmp"
  local in_section=false

  while IFS= read -r line; do
    if [[ "$line" == "[$section]" ]]; then
      in_section=true
    elif [[ "$line" == "["* ]]; then
      in_section=false
    fi

    if $in_section && [[ "$line" =~ ^[[:space:]]*${key}[[:space:]]*= ]] && [[ "$line" == *"$old"* ]]; then
      line="${line//$old/$new}"
    fi

    echo "$line"
  done < "$file" > "$temp_file"
  mv "$temp_file" "$file"
}

# ── Inline table helpers ──────────────────────────────────────────────

: <<'DOC'
Sets a field within a TOML inline table on a single line.
If the field exists, replaces its value. If not, inserts before the closing brace.
Returns the modified line on stdout.

  toml_inline_set 'foo = { path = "bar", version = "=1.0" }' "version" '"=2.0"'
  toml_inline_set 'foo = { path = "bar" }' "version" '"=2.0"'
DOC
function toml_inline_set() {
  local line="$1" field="$2" value="$3"

  if [[ "$line" == *"${field}"* ]]; then
    echo "$line" | sed -E "s/${field}[[:space:]]*=[[:space:]]*\"[^\"]*\"/${field} = ${value}/"
  else
    echo "$line" | sed -E "s/[[:space:]]*\}/, ${field} = ${value} }/"
  fi
}

# ── Private helpers ───────────────────────────────────────────────────

function __toml__append_to_section() {
  local file="$1" section="$2" key="$3" value="$4"
  local temp_file="${file}.tmp"
  local in_section=false appended=false

  while IFS= read -r line; do
    if [[ "$line" == "[$section]" ]]; then
      in_section=true
      echo "$line"
      continue
    elif $in_section && [[ "$line" == "["* ]]; then
      if ! $appended; then
        echo "${key} = ${value}"
        appended=true
      fi
      in_section=false
    fi
    echo "$line"
  done < "$file" > "$temp_file"

  # If section existed but was at EOF, append there
  if $in_section && ! $appended; then
    echo "${key} = ${value}" >> "$temp_file"
  fi

  # If section didn't exist at all, create it
  if ! $appended && ! $in_section; then
    printf '\n[%s]\n%s = %s\n' "$section" "$key" "$value" >> "$temp_file"
  fi

  mv "$temp_file" "$file"
}
