#!/usr/bin/env bash
# LSMC Atlas - Environment Activation Script
# ==========================================
#
# Source this script from the repository root:
#   source ./activate
#
# What it does:
#   1. Activates LSMC_ATLAS conda environment (if available)
#   2. Installs atlas CLI in editable mode (if needed)
#   3. Enables atlas shell completion
#   4. Exports TapDB/AWS defaults for Atlas runtime

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    echo "Error: This script must be sourced, not executed."
    echo "Usage: source ./activate"
    exit 1
fi

_atlas_script_path() {
    if [[ -n "${ZSH_VERSION:-}" ]]; then
        printf '%s\n' "${(%):-%x}"
    elif [[ -n "${BASH_SOURCE[0]:-}" ]]; then
        printf '%s\n' "${BASH_SOURCE[0]}"
    else
        printf '%s\n' "$0"
    fi
}

_ATLAS_SCRIPT_PATH="$(_atlas_script_path)"
LSMC_ATLAS_ROOT="$(cd "$(dirname "${_ATLAS_SCRIPT_PATH}")" && pwd)"
unset -f _atlas_script_path
unset _ATLAS_SCRIPT_PATH

_GREEN='\033[0;32m'
_YELLOW='\033[1;33m'
_BLUE='\033[0;34m'
_CYAN='\033[0;36m'
_NC='\033[0m'
_ATLAS_PYTHON=""
_ATLAS_ENV_BASE="LSMC_ATLAS"

_atlas_truthy() {
    case "${1:-}" in
        1|true|TRUE|yes|YES|on|ON) return 0 ;;
        *) return 1 ;;
    esac
}

_atlas_sanitize_deployment_code() {
    local raw_value="$1"
    local sanitized=""
    sanitized="$(printf '%s' "$raw_value" | LC_ALL=C sed -E 's/[^A-Za-z0-9._-]+/-/g; s/^-+//; s/-+$//')"
    if [[ -z "$sanitized" ]]; then
        sanitized="local"
    fi
    printf '%s\n' "$sanitized"
}

_atlas_config_dir_name() {
    printf 'lsmc-atlas-%s\n' "${_ATLAS_ENV_NAME#${_ATLAS_ENV_BASE}-}"
}

_atlas_config_filename() {
    printf 'lsmc-atlas-config-%s.yaml\n' "${_ATLAS_ENV_NAME#${_ATLAS_ENV_BASE}-}"
}

_atlas_deployment_code="${ATLAS_DEPLOYMENT_CODE:-${DEPLOYMENT_CODE:-${LSMC_DEPLOYMENT_CODE:-local}}}"
_atlas_deployment_code="$(_atlas_sanitize_deployment_code "${_atlas_deployment_code}")"
_ATLAS_ENV_NAME="${_ATLAS_ENV_BASE}-${_atlas_deployment_code}"
unset _atlas_deployment_code

_atlas_activation_fail() {
    echo -e "  ${_YELLOW}✗${_NC} $1"
    echo -e "     Atlas requires conda environment: ${_CYAN}${_ATLAS_ENV_NAME}${_NC}"
    echo -e "     CONDA_DEFAULT_ENV=${CONDA_DEFAULT_ENV:-<unset>}"
    echo -e "     CONDA_PREFIX=${CONDA_PREFIX:-<unset>}"
}

_atlas_resolve_local_repo() {
    local module_dir="$1"
    shift
    local candidate=""
    local candidate_path=""
    local fallback=""
    for candidate in "$@"; do
        [[ -d "$candidate" ]] || continue
        candidate_path="$(cd "$candidate" 2>/dev/null && pwd)"
        [[ -n "$candidate_path" ]] || continue
        [[ -d "${candidate_path}/${module_dir}" ]] || continue
        if [[ -d "${candidate_path}/.git" ]]; then
            printf '%s\n' "$candidate_path"
            return 0
        fi
        if [[ -z "$fallback" ]]; then
            fallback="$candidate_path"
        fi
    done
    [[ -n "$fallback" ]] && printf '%s\n' "$fallback"
}

_atlas_module_is_from_repo() {
    local module_name="$1"
    local repo_root="$2"
    "${_ATLAS_PYTHON:-python}" - "$module_name" "$repo_root" <<'PY' >/dev/null 2>&1
import importlib
import pathlib
import sys

module = importlib.import_module(sys.argv[1])
repo_root = pathlib.Path(sys.argv[2]).resolve()
module_file = getattr(module, "__file__", "")
if not module_file:
    raise SystemExit(1)
module_path = pathlib.Path(module_file).resolve()
raise SystemExit(0 if module_path == repo_root or repo_root in module_path.parents else 1)
PY
}

_atlas_distribution_is_editable_from_repo() {
    local dist_name="$1"
    local repo_root="$2"
    local editable_location=""

    editable_location="$("${_ATLAS_PYTHON:-python}" -m pip show "$dist_name" 2>/dev/null | awk -F': ' '/^Editable project location:/ {print $2; exit}')"
    [[ -n "$editable_location" ]] || return 1

    editable_location="$(cd "$editable_location" 2>/dev/null && pwd)"
    [[ -n "$editable_location" ]] || return 1
    [[ "$editable_location" == "$repo_root" ]]
}

_atlas_ensure_editable_repo() {
    local label="$1"
    local module_name="$2"
    local repo_root="$3"
    local extras="${4:-}"
    local dist_name="${5:-}"
    local install_target=""
    if [[ -z "$repo_root" ]]; then
        return 0
    fi
    if [[ -n "$dist_name" ]]; then
        if _atlas_distribution_is_editable_from_repo "$dist_name" "$repo_root"; then
            echo -e "  ${_GREEN}✓${_NC} Using local ${label} checkout: ${repo_root}"
            return 0
        fi
    elif _atlas_module_is_from_repo "$module_name" "$repo_root"; then
        echo -e "  ${_GREEN}✓${_NC} Using local ${label} checkout: ${repo_root}"
        return 0
    fi
    install_target="${repo_root}${extras}"
    echo -e "  ${_CYAN}→${_NC} Installing local ${label} checkout..."
    if ! "${_ATLAS_PYTHON:-python}" -m pip install --no-deps -e "$install_target" -q; then
        echo -e "  ${_YELLOW}⚠${_NC} Failed to install local ${label} checkout from ${repo_root}"
        return 1
    fi
    if [[ -n "$dist_name" ]]; then
        if ! _atlas_distribution_is_editable_from_repo "$dist_name" "$repo_root"; then
            echo -e "  ${_YELLOW}⚠${_NC} ${label} is not installed editable from ${repo_root}"
            return 1
        fi
    elif ! _atlas_module_is_from_repo "$module_name" "$repo_root"; then
        echo -e "  ${_YELLOW}⚠${_NC} ${label} still resolves outside ${repo_root}"
        return 1
    fi
    echo -e "  ${_GREEN}✓${_NC} Using local ${label} checkout: ${repo_root}"
}

_atlas_prepare_tapdb_config_path() {
    local client_id="$1"
    local namespace="$2"
    local explicit_path="${TAPDB_CONFIG_PATH:-}"
    local xdg_config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
    local deployment_code="${ATLAS_DEPLOYMENT_CODE:-${DEPLOYMENT_CODE:-${LSMC_DEPLOYMENT_CODE:-local}}}"
    local scoped_namespace=""
    deployment_code="$(_atlas_sanitize_deployment_code "${deployment_code}")"
    scoped_namespace="${namespace}-${deployment_code}"
    local user_dir="${xdg_config_home}/tapdb/${client_id}/${scoped_namespace}"
    local user_path="${user_dir}/tapdb-config.yaml"
    local repo_template="$LSMC_ATLAS_ROOT/config/tapdb-config-${namespace}.yaml"

    if [[ -n "$explicit_path" ]]; then
        printf '%s\n' "$explicit_path"
        return 0
    fi

    if [[ -f "$user_path" ]]; then
        chmod 600 "$user_path" 2>/dev/null || true
        printf '%s\n' "$user_path"
        return 0
    fi

    if [[ ! -f "$repo_template" ]]; then
        printf '%s\n' "$user_path"
        return 0
    fi

    mkdir -p "$user_dir" || return 1
    cp "$repo_template" "$user_path" || return 1
    chmod 600 "$user_path" || return 1
    echo -e "  ${_CYAN}→${_NC} Created secure TapDB config copy: ${user_path}" >&2
    printf '%s\n' "$user_path"
}

echo -e "${_BLUE}Activating LSMC Atlas environment...${_NC}"

# 1. Activate conda environment (install if needed)
if command -v conda &> /dev/null; then
    source "$(conda info --base)/etc/profile.d/conda.sh" 2>/dev/null || true

    if conda info --envs | grep -q "${_ATLAS_ENV_NAME}"; then
        echo -e "  ${_GREEN}✓${_NC} Activating conda environment: ${_ATLAS_ENV_NAME}"
        if ! conda activate "${_ATLAS_ENV_NAME}"; then
            echo -e "  ${_YELLOW}⚠${_NC} Failed to activate conda environment: ${_ATLAS_ENV_NAME}."
        fi
        if [[ -n "${CONDA_PREFIX:-}" ]] && [[ -d "${CONDA_PREFIX}/bin" ]]; then
            export PATH="${CONDA_PREFIX}/bin:$PATH"
        fi
    else
        echo -e "  ${_YELLOW}⚠${_NC} Conda environment '${_ATLAS_ENV_NAME}' not found."
        if [[ -f "$LSMC_ATLAS_ROOT/atlas_env.yaml" ]]; then
            echo -e "  ${_CYAN}→${_NC} Installing conda environment from atlas_env.yaml..."
            if conda env create -n "${_ATLAS_ENV_NAME}" -f "$LSMC_ATLAS_ROOT/atlas_env.yaml"; then
                echo -e "  ${_GREEN}✓${_NC} Activating conda environment: ${_ATLAS_ENV_NAME}"
                if ! conda activate "${_ATLAS_ENV_NAME}"; then
                    echo -e "  ${_YELLOW}⚠${_NC} Failed to activate conda environment: ${_ATLAS_ENV_NAME}."
                fi
                if [[ -n "${CONDA_PREFIX:-}" ]] && [[ -d "${CONDA_PREFIX}/bin" ]]; then
                    export PATH="${CONDA_PREFIX}/bin:$PATH"
                fi
            else
                echo -e "  ${_YELLOW}⚠${_NC} Failed to create conda environment."
            fi
        fi
    fi
else
    echo -e "  ${_YELLOW}⚠${_NC} Conda not found. Ensure dependencies are installed."
fi

_ATLAS_CONDA_PREFIX_BASENAME=""
if [[ -n "${CONDA_PREFIX:-}" ]]; then
    _ATLAS_CONDA_PREFIX_BASENAME="$(basename "${CONDA_PREFIX}")"
fi

if [[ "${CONDA_DEFAULT_ENV:-}" != "${_ATLAS_ENV_NAME}" ]] || [[ -z "${CONDA_PREFIX:-}" ]] || [[ "${_ATLAS_CONDA_PREFIX_BASENAME}" != "${_ATLAS_ENV_NAME}" ]] || [[ ! -x "${CONDA_PREFIX}/bin/python" ]]; then
    _atlas_activation_fail "Atlas activation did not select the expected conda environment."
    unset _ATLAS_CONDA_PREFIX_BASENAME
    return 1
fi
unset _ATLAS_CONDA_PREFIX_BASENAME

# Ensure the active environment's bin directory wins over any stale global CLI.
if [[ -n "${CONDA_PREFIX:-}" ]] && [[ -x "${CONDA_PREFIX}/bin/python" ]]; then
    _ATLAS_PYTHON="${CONDA_PREFIX}/bin/python"
elif command -v python3 &> /dev/null; then
    _ATLAS_PYTHON="$(command -v python3)"
elif command -v python &> /dev/null; then
    _ATLAS_PYTHON="$(command -v python)"
fi

if [[ -n "${_ATLAS_PYTHON}" ]]; then
    _ATLAS_PYTHON_BIN="$(dirname "${_ATLAS_PYTHON}")"
    _ATLAS_SCRIPTS_DIR="$("${_ATLAS_PYTHON}" -c 'import sysconfig; print(sysconfig.get_path("scripts") or "")' 2>/dev/null || true)"
    if [[ -n "${_ATLAS_SCRIPTS_DIR}" ]] && [[ -d "${_ATLAS_SCRIPTS_DIR}" ]]; then
        export PATH="${_ATLAS_SCRIPTS_DIR}:$PATH"
    fi
    if [[ -d "${_ATLAS_PYTHON_BIN}" ]]; then
        export PATH="${_ATLAS_PYTHON_BIN}:$PATH"
    fi
fi

# 2. Install local editable checkouts for the active workspace
if ! _atlas_ensure_editable_repo "Atlas" "app" "$LSMC_ATLAS_ROOT" "" "lsmc-atlas"; then
    return 1
fi

_ATLAS_TAPDB_REPO="$(_atlas_resolve_local_repo \
    daylily_tapdb \
    "$LSMC_ATLAS_ROOT/../../daylily/daylily-tapdb" \
    "$LSMC_ATLAS_ROOT/../../daylily/lims_repos/daylily-tapdb"
)"
if _atlas_truthy "${USE_LOCAL_DAYLILY_TAPDB:-0}"; then
    if ! _atlas_ensure_editable_repo "daylily-tapdb" "daylily_tapdb" "${_ATLAS_TAPDB_REPO:-}" "[cli,admin,aurora,dev]" "daylily-tapdb"; then
        return 1
    fi
else
    echo -e "  ${_GREEN}✓${_NC} Using packaged daylily-tapdb from ${_ATLAS_ENV_NAME}"
fi

_ATLAS_DAYCOG_REPO="$(_atlas_resolve_local_repo \
    daylily_cognito \
    "$LSMC_ATLAS_ROOT/../../daylily/daylily-cognito" \
    "$LSMC_ATLAS_ROOT/../../daylily/lims_repos/daylily-cognito"
)"
if _atlas_truthy "${USE_LOCAL_DAYLILY_COGNITO:-0}"; then
    if ! _atlas_ensure_editable_repo "daylily-cognito" "daylily_cognito" "${_ATLAS_DAYCOG_REPO:-}" "" "daylily-cognito"; then
        return 1
    fi
else
    echo -e "  ${_GREEN}✓${_NC} Using packaged daylily-cognito from ${_ATLAS_ENV_NAME}"
fi

_ATLAS_CLI_CORE_REPO="$(_atlas_resolve_local_repo \
    cli_core_yo \
    "$LSMC_ATLAS_ROOT/../../daylily/cli-core-yo" \
    "$LSMC_ATLAS_ROOT/../../daylily/lims_repos/cli-core-yo"
)"
if _atlas_truthy "${USE_LOCAL_CLI_CORE_YO:-0}"; then
    if ! _atlas_ensure_editable_repo "cli-core-yo" "cli_core_yo" "${_ATLAS_CLI_CORE_REPO:-}" "" "cli-core-yo"; then
        return 1
    fi
else
    echo -e "  ${_GREEN}✓${_NC} Using packaged cli-core-yo from ${_ATLAS_ENV_NAME}"
fi

if command -v rehash >/dev/null 2>&1; then
    rehash
elif command -v hash >/dev/null 2>&1; then
    hash -r 2>/dev/null || true
fi

# 3. Enable tab completion for interactive shells only.
if [[ "$-" == *i* ]]; then
    if [[ -n "${ZSH_VERSION:-}" ]]; then
        if _ATLAS_COMPLETION="$(atlas --show-completion zsh 2>/dev/null)" && eval "${_ATLAS_COMPLETION}" 2>/dev/null; then
            echo -e "  ${_GREEN}✓${_NC} Enabled tab completion for 'atlas' (zsh)"
        fi
        unset _ATLAS_COMPLETION
    elif [[ -n "${BASH_VERSION:-}" ]]; then
        if _ATLAS_COMPLETION="$(atlas --show-completion bash 2>/dev/null)" && eval "${_ATLAS_COMPLETION}" 2>/dev/null; then
            echo -e "  ${_GREEN}✓${_NC} Enabled tab completion for 'atlas' (bash)"
        fi
        unset _ATLAS_COMPLETION
    fi
fi

# 4. Export Atlas/TapDB defaults
export LSMC_ATLAS_ROOT
export AWS_PROFILE="${AWS_PROFILE:-lsmc}"
export AWS_REGION="${AWS_REGION:-us-west-2}"
export DATABASE_BACKEND="${DATABASE_BACKEND:-tapdb}"
export DATABASE_TARGET="${DATABASE_TARGET:-local}"
export TAPDB_ENV="${TAPDB_ENV:-dev}"
export TAPDB_CLIENT_ID="${TAPDB_CLIENT_ID:-atlas}"
export TAPDB_DATABASE_NAME="${TAPDB_DATABASE_NAME:-lsmc-atlas}"
_ATLAS_DEFAULT_TAPDB_CONFIG_PATH="$LSMC_ATLAS_ROOT/config/tapdb-config-${TAPDB_DATABASE_NAME}.yaml"
_ATLAS_USER_TAPDB_CONFIG_PATH="$(_atlas_prepare_tapdb_config_path "$TAPDB_CLIENT_ID" "$TAPDB_DATABASE_NAME")" || {
    echo -e "  ${_YELLOW}⚠${_NC} Failed to prepare secure TapDB config path."
    return 1
}
export TAPDB_CONFIG_PATH="${_ATLAS_USER_TAPDB_CONFIG_PATH}"
export TAPDB_STRICT_NAMESPACE="${TAPDB_STRICT_NAMESPACE:-1}"

echo -e "  ${_GREEN}✓${_NC} AWS_PROFILE=${AWS_PROFILE}"
echo -e "  ${_GREEN}✓${_NC} AWS_REGION=${AWS_REGION}"
echo -e "  ${_GREEN}✓${_NC} TAPDB_CLIENT_ID=${TAPDB_CLIENT_ID}"
echo -e "  ${_GREEN}✓${_NC} TAPDB_DATABASE_NAME=${TAPDB_DATABASE_NAME}"
echo -e "  ${_GREEN}✓${_NC} TAPDB_ENV=${TAPDB_ENV}"
echo -e "  ${_GREEN}✓${_NC} TAPDB_STRICT_NAMESPACE=${TAPDB_STRICT_NAMESPACE}"
echo -e "  ${_GREEN}✓${_NC} TAPDB_CONFIG_PATH=${TAPDB_CONFIG_PATH}"

if [[ ! -f "$TAPDB_CONFIG_PATH" ]]; then
    echo -e "  ${_YELLOW}⚠${_NC} TapDB scoped config not found at ${TAPDB_CONFIG_PATH}"
    echo -e "     Create this file to avoid fallback to unrelated TapDB configs."
fi

if [[ -n "${DATABASE_URL:-}" ]]; then
    echo -e "  ${_GREEN}✓${_NC} DATABASE_URL already set"
else
    echo -e "  ${_CYAN}→${_NC} DATABASE_URL is resolved at runtime from tapdb config"
    echo -e "     Use ${_CYAN}atlas db build --target local${_NC} to bootstrap local runtime"
fi

# 5. Check for config file
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/lsmc-atlas"
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/$(_atlas_config_dir_name)"
CONFIG_FILE="$CONFIG_DIR/$(_atlas_config_filename)"
if [[ -f "$CONFIG_FILE" ]]; then
    echo -e "  ${_GREEN}✓${_NC} Config file: $CONFIG_FILE"
else
    echo -e "  ${_YELLOW}⚠${_NC} Config file not found: $CONFIG_FILE"
    echo -e "     Run ${_CYAN}atlas config init${_NC} to create it"
fi

# 6. Create deactivate function
atlas_deactivate() {
    unset LSMC_ATLAS_ROOT
    unset DATABASE_URL

    if [[ "$CONDA_DEFAULT_ENV" == "${_ATLAS_ENV_NAME}" ]]; then
        conda deactivate 2>/dev/null
    fi

    echo "LSMC Atlas environment deactivated."
    unset -f atlas_deactivate
}

echo ""
echo -e "${_CYAN}LSMC Atlas environment activated!${_NC}"
echo ""

echo "Command groups:"
echo ""
echo -e "  ${_CYAN}atlas server${_NC}    start, stop, status, logs, restart, worker"
echo -e "  ${_CYAN}atlas db${_NC}        build, seed, reset, nuke"
echo -e "  ${_CYAN}atlas test${_NC}      run, all, db, cov, watch"
echo -e "  ${_CYAN}atlas quality${_NC}   lint, format, typecheck, check, templates"
echo -e "  ${_CYAN}atlas users${_NC}     list, groups, make-admin, remove-admin, create, info"
echo -e "  ${_CYAN}atlas cognito${_NC}   bind, import, sync-config, status, validate"
echo -e "  ${_CYAN}atlas config${_NC}    path, init, show, validate, edit, reset, clean, shell, routes, status"
echo -e "  ${_CYAN}atlas env${_NC}       status, activate, deactivate, reset"
echo -e "  ${_CYAN}atlas certs${_NC}     install, create, status"
echo -e "  ${_CYAN}tapdb${_NC}           shared DB/runtime lifecycle"
echo -e "  ${_CYAN}daycog${_NC}          shared Cognito pool/app/user lifecycle"
echo ""
echo -e "  ${_GREEN}atlas version${_NC}           Show version"
echo -e "  ${_GREEN}atlas info${_NC}              Show system info"
echo -e "  ${_GREEN}atlas --help${_NC}            Show all available commands"
echo -e "  ${_GREEN}atlas_deactivate${_NC}        Deactivate this environment"
echo ""

unset _ATLAS_CLI_CORE_REPO
unset _ATLAS_DAYCOG_REPO
unset _ATLAS_TAPDB_REPO
unset _ATLAS_USER_TAPDB_CONFIG_PATH
