#!/usr/bin/env bash
# ensure_repo_synced — Garantiza que un directorio tenga repo Gitea y este
# sincronizado: crea el repo remoto si no existe, inicializa .git si falta,
# commitea cambios pendientes y pushea a origin.
#
# Pipeline que compone gitea_create_repo + gitea_push_directory.
#
# Uso:
#   ensure_repo_synced <directory> [owner] [repo_name] [branch] [commit_msg]
#
# Defaults:
#   owner       = dataforge
#   repo_name   = basename(directory)
#   branch      = master
#   commit_msg  = "chore: sync from fn_registry"

ensure_repo_synced() {
    local directory="$1"
    local owner="${2:-dataforge}"
    local repo_name="$3"
    local branch="${4:-master}"
    local commit_msg="${5:-chore: sync from fn_registry}"

    if [[ -z "$directory" ]]; then
        echo "ensure_repo_synced: se requiere directory" >&2
        return 1
    fi
    if [[ ! -d "$directory" ]]; then
        echo "ensure_repo_synced: directorio '$directory' no existe" >&2
        return 1
    fi
    if [[ -z "$repo_name" ]]; then
        repo_name=$(basename "$(realpath "$directory")")
    fi

    if [[ -z "${GITEA_URL:-}" || -z "${GITEA_TOKEN:-}" ]]; then
        echo "ensure_repo_synced: GITEA_URL y GITEA_TOKEN deben estar seteados" >&2
        return 1
    fi

    # Localizar las funciones companeras: por env var o por path relativo al
    # propio script si esta disponible.
    local script_dir="${FN_REGISTRY_INFRA_DIR:-}"
    if [[ -z "$script_dir" ]]; then
        local self="${BASH_SOURCE[0]:-$0}"
        if [[ -f "$self" ]]; then
            script_dir="$(cd "$(dirname "$self")" && pwd)"
        fi
    fi
    if [[ -z "$script_dir" || ! -f "$script_dir/gitea_create_repo.sh" ]]; then
        # Fallback: buscar en FN_REGISTRY_ROOT/bash/functions/infra
        local root="${FN_REGISTRY_ROOT:-$(cd "$(pwd)" && while [[ "$PWD" != "/" && ! -f "registry.db" ]]; do cd ..; done && pwd)}"
        script_dir="$root/bash/functions/infra"
    fi
    if [[ ! -f "$script_dir/gitea_create_repo.sh" ]]; then
        echo "ensure_repo_synced: no encuentro gitea_create_repo.sh (script_dir=$script_dir). Setea FN_REGISTRY_INFRA_DIR" >&2
        return 1
    fi
    # shellcheck source=./gitea_create_repo.sh
    source "$script_dir/gitea_create_repo.sh"
    # shellcheck source=./gitea_push_directory.sh
    source "$script_dir/gitea_push_directory.sh"

    echo "ensure_repo_synced: $directory → $owner/$repo_name [$branch]" >&2

    # 1. Asegurar repo remoto en Gitea (idempotente — 409 si existe)
    if ! gitea_create_repo "$owner" "$repo_name" "false" "Synced from fn_registry" >/dev/null; then
        echo "ensure_repo_synced: fallo creando/comprobando repo remoto" >&2
        return 1
    fi

    # 2. Inicializar .git, commitear y pushear
    # gitea_push_directory ya hace commit con su mensaje por defecto. Para
    # respetar commit_msg custom, hacemos commit aqui antes si hay cambios.
    if [[ -d "$directory/.git" ]]; then
        local git_status
        git_status=$(git -C "$directory" status --porcelain)
        if [[ -n "$git_status" ]]; then
            echo "ensure_repo_synced: commiteando cambios con mensaje: $commit_msg" >&2
            git -C "$directory" add -A
            git -C "$directory" \
                -c user.email="agent@fn-registry" -c user.name="fn-registry agent" \
                commit -m "$commit_msg"
        fi
    fi

    if ! gitea_push_directory "$directory" "$owner" "$repo_name" "$branch"; then
        echo "ensure_repo_synced: fallo en gitea_push_directory" >&2
        return 1
    fi

    echo "ensure_repo_synced: ok '$owner/$repo_name'" >&2
}

# Si se invoca como script (no source), ejecutar la funcion.
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    ensure_repo_synced "$@"
fi
