#!/usr/bin/env bash
# verify_file_hash
# ----------------
# Calcula el hash de un archivo con el algoritmo indicado (md5, sha1, sha256, sha512)
# y opcionalmente lo compara con un hash esperado.
#
# USO (directo):
#   verify_file_hash <archivo> <md5|sha1|sha256|sha512> [hash_esperado]
#
# Depende de: md5sum, sha1sum, sha256sum, sha512sum

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../shell/bash_colors.sh"
source "$SCRIPT_DIR/../shell/bash_log.sh"
bash_colors
bash_log_init

# ─── Funciones puras ──────────────────────────────────────────────────────────

_hash_select_cmd() {
    local algo="$1"
    case "$algo" in
        md5)    echo "md5sum" ;;
        sha1)   echo "sha1sum" ;;
        sha256) echo "sha256sum" ;;
        sha512) echo "sha512sum" ;;
        *)      echo "" ;;
    esac
}

_hash_hashes_match() {
    local a="${1,,}"
    local b="${2,,}"
    [[ "$a" == "$b" ]]
}

# ─── Funciones de efecto ──────────────────────────────────────────────────────

_hash_compute() {
    local cmd="$1"
    local file="$2"
    "$cmd" "$file" 2>/dev/null | awk '{print $1}'
}

# ─── Punto de entrada ─────────────────────────────────────────────────────────

verify_file_hash() {
    local file="$1"
    local algorithm="$2"
    local expected_hash="${3:-}"

    if [[ -z "$file" || -z "$algorithm" ]]; then
        error "verify_file_hash: uso: verify_file_hash <archivo> <md5|sha1|sha256|sha512> [hash_esperado]" >&2
        return 1
    fi

    if [[ ! -f "$file" ]]; then
        error "verify_file_hash: archivo no encontrado: $file" >&2
        return 1
    fi

    local cmd
    cmd="$(_hash_select_cmd "$algorithm")"

    if [[ -z "$cmd" ]]; then
        error "verify_file_hash: algoritmo no válido '$algorithm'. Use: md5|sha1|sha256|sha512" >&2
        return 1
    fi

    if ! command -v "$cmd" &>/dev/null; then
        error "verify_file_hash: '$cmd' no está disponible" >&2
        return 1
    fi

    info "Calculando ${algorithm^^} de: $(basename "$file")"
    local hash
    hash="$(_hash_compute "$cmd" "$file")"

    echo ""
    echo -e "  ${CYAN}Archivo:${NC} ${file}"
    echo -e "  ${CYAN}${algorithm^^}:${NC}    ${hash}"
    echo ""

    if [[ -n "$expected_hash" ]]; then
        if _hash_hashes_match "$hash" "$expected_hash"; then
            echo -e "  ${GREEN}[COINCIDE]${NC} La integridad del archivo es correcta"
        else
            echo -e "  ${RED}[NO COINCIDE]${NC} El archivo puede estar corrupto o modificado"
            echo ""
            echo -e "  ${CYAN}Calculado:${NC} ${hash}"
            echo -e "  ${CYAN}Esperado: ${NC} ${expected_hash}"
            return 1
        fi
    fi
}

# Ejecutar si se llama directamente
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    verify_file_hash "$@"
fi
