#!/usr/bin/env bash
# Resolve workspace layout: .run/run.config.toml (config) or run/ (legacy).
# Sets WORKSPACE_DIR, RUN_DIR, PACKAGE_DIR, RUN_LAYOUT, ENV_FILE, WORKSPACE_CONFIG.

resolve_workspace() {
  local start="${1:-${PWD}}"
  local dir="" parent=""
  local legacy_cfg=""

  WORKSPACE_DIR=""
  if [ -n "${RUN_WORKSPACE_DIR:-}" ]; then
    WORKSPACE_DIR="$(cd "${RUN_WORKSPACE_DIR}" && pwd)"
  else
    dir="$(cd "${start}" 2>/dev/null && pwd || pwd)"
    while [ -n "${dir}" ]; do
      if [ -f "${dir}/.run/run.config.toml" ] || [ -f "${dir}/.run/run.config.json" ] \
        || [ -f "${dir}/run.config.toml" ] || [ -f "${dir}/run.config.json" ]; then
        WORKSPACE_DIR="${dir}"
        break
      fi
      if [ -f "${dir}/run/run.sh" ]; then
        WORKSPACE_DIR="${dir}"
        break
      fi
      if [ -f "${dir}/run.sh" ] && [ -d "${dir}/scripts" ]; then
        WORKSPACE_DIR="${dir}"
        break
      fi
      parent="$(dirname "${dir}")"
      [ "${parent}" = "${dir}" ] && break
      dir="${parent}"
    done
  fi

  [ -n "${WORKSPACE_DIR}" ] || return 1

  if [ -f "${WORKSPACE_DIR}/.run/run.config.toml" ] || [ -f "${WORKSPACE_DIR}/.run/run.config.json" ] \
    || [ -f "${WORKSPACE_DIR}/run.config.toml" ] || [ -f "${WORKSPACE_DIR}/run.config.json" ]; then
    RUN_LAYOUT=config
  elif [ -f "${WORKSPACE_DIR}/run/run.sh" ]; then
    RUN_LAYOUT=legacy
  elif [ -n "${RUN_WORKSPACE_DIR:-}" ]; then
    RUN_LAYOUT=config
  elif [ -f "${WORKSPACE_DIR}/run.sh" ] && [ -d "${WORKSPACE_DIR}/scripts" ]; then
    RUN_LAYOUT=checkout
  else
    return 1
  fi

  case "${RUN_LAYOUT}" in
    config)
      RUN_DIR="${WORKSPACE_DIR}/.run"
      PACKAGE_DIR="${RUN_PACKAGE_DIR:-}"
      if [ -z "${PACKAGE_DIR}" ] || [ ! -f "${PACKAGE_DIR}/run.sh" ]; then
        PACKAGE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
      fi
      ;;
    legacy)
      RUN_DIR="${WORKSPACE_DIR}/run"
      PACKAGE_DIR="${RUN_DIR}"
      ;;
    checkout)
      RUN_DIR="${WORKSPACE_DIR}"
      PACKAGE_DIR="${WORKSPACE_DIR}"
      ;;
  esac

  WORKSPACE_CONFIG="${RUN_DIR}/run.config.toml"
  ENV_FILE="${RUN_DIR}/.env"
  mkdir -p "${RUN_DIR}"

  # Prefer an existing file: toml, then json. Migrate json → toml when needed.
  if [ "${RUN_LAYOUT}" = config ]; then
    legacy_cfg="${WORKSPACE_DIR}/run.config.toml"
    if [ -f "${legacy_cfg}" ] && [ ! -f "${WORKSPACE_CONFIG}" ]; then
      mv "${legacy_cfg}" "${WORKSPACE_CONFIG}"
    fi
    legacy_cfg="${WORKSPACE_DIR}/run.config.json"
    if [ -f "${legacy_cfg}" ] && [ ! -f "${WORKSPACE_CONFIG}" ] && [ ! -f "${RUN_DIR}/run.config.json" ]; then
      mv "${legacy_cfg}" "${RUN_DIR}/run.config.json"
    fi
    if [ -f "${RUN_DIR}/run.config.json" ] && [ ! -f "${WORKSPACE_CONFIG}" ]; then
      migrate_json_config_to_toml "${RUN_DIR}/run.config.json" "${WORKSPACE_CONFIG}"
    elif [ -f "${WORKSPACE_CONFIG}" ]; then
      :
    elif [ -f "${RUN_DIR}/run.config.json" ]; then
      WORKSPACE_CONFIG="${RUN_DIR}/run.config.json"
    fi
  fi

  export WORKSPACE_DIR RUN_DIR PACKAGE_DIR RUN_LAYOUT WORKSPACE_CONFIG ENV_FILE
}

# Convert a sectioned or flat run.config.json into run.config.toml, then drop JSON.
migrate_json_config_to_toml() {
  local src="$1" dst="$2"
  [ -f "${src}" ] || return 0
  python3 - "${src}" "${dst}" <<'PY' || return 1
import json, os, sys

src, dst = sys.argv[1], sys.argv[2]
with open(src, encoding="utf-8") as fh:
    data = json.load(fh)
if not isinstance(data, dict):
    sys.exit(1)

def emit_value(value):
    if isinstance(value, bool):
        return "true" if value else "false"
    if isinstance(value, int) and not isinstance(value, bool):
        return str(value)
    if isinstance(value, float):
        return repr(value)
    if value is None:
        return '""'
    text = str(value)
    if text == "":
        return '""'
    escaped = text.replace("\\", "\\\\").replace('"', '\\"')
    return f'"{escaped}"'

def emit_table(name, section, out):
    if not isinstance(section, dict) or not section:
        return
    # Nested object-of-object (essential): one empty/option table per key.
    if name == "essential" or all(isinstance(v, dict) for v in section.values()):
        for key, value in section.items():
            if str(key).startswith("_"):
                continue
            if isinstance(value, dict):
                out.append(f"[{name}.{key}]")
                for inner_k, inner_v in value.items():
                    if str(inner_k).startswith("_"):
                        continue
                    out.append(f"{inner_k} = {emit_value(inner_v)}")
                out.append("")
            else:
                out.append(f"[{name}]")
                out.append(f"{key} = {emit_value(value)}")
                out.append("")
        return
    out.append(f"[{name}]")
    for key, value in section.items():
        if str(key).startswith("_"):
            continue
        out.append(f"{key} = {emit_value(value)}")
    out.append("")

lines = [
    "# Migrated from run.config.json by run-stack.",
    "",
]
# Sectioned file: values are objects. Flat file: promote into one [other] table.
sectioned = any(
    isinstance(v, dict) and not k.startswith("_") for k, v in data.items()
)
if sectioned:
    for key, value in data.items():
        if key.startswith("_"):
            continue
        if isinstance(value, dict):
            emit_table(key, value, lines)
        else:
            emit_table("other", {key: value}, lines)
else:
    emit_table("other", {k: v for k, v in data.items() if not k.startswith("_")}, lines)

tmp = dst + ".tmp"
with open(tmp, "w", encoding="utf-8") as fh:
    fh.write("\n".join(lines).rstrip() + "\n")
os.replace(tmp, dst)
os.remove(src)
print(f"Migrated {src} → {dst}", file=sys.stderr)
PY
  WORKSPACE_CONFIG="${dst}"
}

ensure_workspace_gitignore() {
  [ "${RUN_LAYOUT}" = config ] || return 0
  local file="${WORKSPACE_DIR}/.gitignore" line=".run/"
  [ -f "${file}" ] || touch "${file}"
  grep -qxF "${line}" "${file}" 2>/dev/null || printf '\n%s\n' "${line}" >> "${file}"
}
