#!/bin/sh
# Bird CLI installer.
# Usage: curl -fsSL https://cli.platform.bird.com/install.sh | sh
#    or: curl -fsSL https://cli.platform.bird.com/install.sh | sh -s -- --version 1.2.3
#    or: sh install.sh --install-dir /opt/bird/bin

set -e

BIRD_CDN_BASE="${BIRD_CDN_BASE:-https://cli.platform.bird.com}"
INSTALL_DIR=""
VERSION=""
OS=""
ARCH=""
TMPDIR_CLEANUP=""
NEEDS_PATH_HELP="false"
RESOLVED_INSTALL_DIR=""
INSTALLED_PATH=""

main() {
    parse_args "$@"
    setup_colors
    detect_platform
    check_dependencies
    resolve_version
    download_and_verify
    install_binary
    print_success
}

parse_args() {
    while [ $# -gt 0 ]; do
        case "$1" in
            --version)
                [ -z "${2:-}" ] && error "--version requires a value"
                VERSION="$2"
                shift 2
                ;;
            --install-dir)
                [ -z "${2:-}" ] && error "--install-dir requires a value"
                INSTALL_DIR="$2"
                shift 2
                ;;
            --help | -h)
                print_help
                exit 0
                ;;
            *)
                error "Unknown option: $1\n\nRun with --help for usage information."
                ;;
        esac
    done
}

setup_colors() {
    BOLD="" DIM="" GREEN="" CYAN="" RED="" YELLOW="" RESET=""
    if [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then
        esc=$(printf '\033')
        BOLD="${esc}[1m" DIM="${esc}[2m" GREEN="${esc}[32m" CYAN="${esc}[36m"
        RED="${esc}[31m" YELLOW="${esc}[33m" RESET="${esc}[0m"
    fi
}

print_help() {
    setup_colors
    cat <<EOF
${BOLD}Bird CLI Installer${RESET}

Install the Bird CLI for managing Bird platform resources.

${BOLD}USAGE${RESET}
    curl -fsSL https://cli.platform.bird.com/install.sh | sh
    curl -fsSL https://cli.platform.bird.com/install.sh | sh -s -- [OPTIONS]
    sh install.sh [OPTIONS]

${BOLD}OPTIONS${RESET}
    --version <version>       Install a specific version (e.g. 1.2.3)
    --install-dir <path>      Install to a custom directory
    -h, --help                Show this help message

${BOLD}INSTALL LOCATIONS${RESET}
    The installer tries these locations in order:
      1. /usr/local/bin   (system-wide, may need sudo)
      2. ~/.local/bin     (XDG standard user bin)
      3. ~/.bird/bin      (Bird-specific fallback)

    Use --install-dir to override this chain.
EOF
}

error() {
    printf '%s\n' "${RED}Error: $1${RESET}" >&2
    exit 1
}

info() { printf '%s\n' "${DIM}$1${RESET}"; }
success() { printf '%s\n' "${GREEN}$1${RESET}"; }
warn() { printf '%s\n' "${YELLOW}$1${RESET}"; }

detect_platform() {
    raw_os="$(uname -s)"
    raw_arch="$(uname -m)"

    case "$raw_os" in
        Darwin | darwin) OS="darwin" ;;
        Linux | linux) OS="linux" ;;
        *) error "Unsupported platform: ${raw_os}/${raw_arch}. Bird CLI supports macOS and Linux on amd64/arm64." ;;
    esac

    case "$raw_arch" in
        x86_64 | amd64) ARCH="amd64" ;;
        arm64 | aarch64) ARCH="arm64" ;;
        *) error "Unsupported platform: ${raw_os}/${raw_arch}. Bird CLI supports macOS and Linux on amd64/arm64." ;;
    esac

    info "Detected platform: ${OS}/${ARCH}"
}

check_dependencies() {
    if command -v curl >/dev/null 2>&1; then
        DOWNLOADER="curl"
    elif command -v wget >/dev/null 2>&1; then
        DOWNLOADER="wget"
    else
        error "curl or wget is required but neither was found."
    fi

    if command -v sha256sum >/dev/null 2>&1; then
        SHA_CMD="sha256sum"
    elif command -v shasum >/dev/null 2>&1; then
        SHA_CMD="shasum -a 256"
    else
        error "sha256sum or shasum is required for checksum verification but neither was found."
    fi

    command -v tar >/dev/null 2>&1 || error "tar is required but was not found."
}

download() {
    url="$1"
    output="$2"
    if [ "$DOWNLOADER" = "curl" ]; then
        curl -fsSL --retry 3 --retry-delay 2 -o "$output" "$url" 2>/dev/null
    else
        wget -q --tries=3 -O "$output" "$url" 2>/dev/null
    fi
}

resolve_version() {
    if [ -n "$VERSION" ]; then
        VERSION="$(printf '%s' "$VERSION" | sed 's/^v//')"
        info "Using specified version: ${VERSION}"
        return
    fi

    info "Fetching latest version..."
    url="${BIRD_CDN_BASE}/releases/latest.txt"
    if [ "$DOWNLOADER" = "curl" ]; then
        VERSION="$(curl -fsSL --retry 3 --retry-delay 2 "$url" 2>/dev/null)" || true
    else
        VERSION="$(wget -qO- --tries=3 "$url" 2>/dev/null)" || true
    fi

    [ -z "$VERSION" ] && error "Failed to fetch latest version. Check your connection or pass --version."
    VERSION="$(printf '%s' "$VERSION" | tr -d '[:space:]' | sed 's/^v//')"
    info "Latest version: ${VERSION}"
}

download_and_verify() {
    archive_name="bird-${OS}-${ARCH}.tar.gz"
    archive_url="${BIRD_CDN_BASE}/releases/v${VERSION}/${archive_name}"
    checksums_url="${BIRD_CDN_BASE}/releases/v${VERSION}/checksums.txt"

    TMPDIR_CLEANUP="$(mktemp -d)"
    trap 'rm -rf "$TMPDIR_CLEANUP"' EXIT INT TERM

    archive_path="${TMPDIR_CLEANUP}/${archive_name}"
    checksums_path="${TMPDIR_CLEANUP}/checksums.txt"

    info "Downloading Bird CLI v${VERSION}..."
    download "$archive_url" "$archive_path" || error "Version ${VERSION} not found at ${BIRD_CDN_BASE}."

    info "Downloading checksums..."
    download "$checksums_url" "$checksums_path" || error "Failed to download checksums for version ${VERSION}."

    info "Verifying checksum..."
    expected_checksum="$(grep "${archive_name}" "$checksums_path" | awk '{print $1}')"
    [ -z "$expected_checksum" ] && error "No checksum found for ${archive_name} in checksums.txt."

    actual_checksum="$($SHA_CMD "$archive_path" | awk '{print $1}')"
    [ "$expected_checksum" != "$actual_checksum" ] && error "Checksum verification failed. The download may be corrupted."
    success "Checksum verified."

    info "Extracting archive..."
    tar -xzf "$archive_path" -C "$TMPDIR_CLEANUP"
    [ -f "${TMPDIR_CLEANUP}/bird" ] || error "Archive did not contain the expected 'bird' binary."
}

shell_rc_file() {
    case "$(basename "${SHELL:-sh}")" in
        zsh) printf '%s' ".zshrc" ;;
        bash) printf '%s' ".bashrc" ;;
        fish) printf '%s' ".config/fish/config.fish" ;;
        *) printf '%s' ".profile" ;;
    esac
}

path_export_cmd() {
    dir="$1"
    case "$(basename "${SHELL:-sh}")" in
        fish) printf '%s' "fish_add_path ${dir}" ;;
        *) printf '%s' "export PATH=\"${dir}:\$PATH\"" ;;
    esac
}

dir_is_writable() {
    dir="$1"
    { [ -d "$dir" ] && [ -w "$dir" ]; } && return 0
    { mkdir -p "$dir" 2>/dev/null && [ -w "$dir" ]; } && return 0
    return 1
}

resolve_install_dir() {
    if [ -n "$INSTALL_DIR" ]; then
        RESOLVED_INSTALL_DIR="$INSTALL_DIR"
        mkdir -p "$RESOLVED_INSTALL_DIR" 2>/dev/null || true
        return
    fi

    for candidate in "/usr/local/bin" "${HOME}/.local/bin" "${HOME}/.bird/bin"; do
        if dir_is_writable "$candidate"; then
            RESOLVED_INSTALL_DIR="$candidate"
            return
        fi
    done

    RESOLVED_INSTALL_DIR="${HOME}/.bird/bin"
    mkdir -p "$RESOLVED_INSTALL_DIR"
}

install_binary() {
    resolve_install_dir
    target_dir="$RESOLVED_INSTALL_DIR"

    if [ -w "$target_dir" ]; then
        install -m 755 "${TMPDIR_CLEANUP}/bird" "${target_dir}/bird"
    elif command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then
        info "Installing to ${target_dir} with sudo..."
        sudo install -m 755 "${TMPDIR_CLEANUP}/bird" "${target_dir}/bird"
    else
        error "Cannot write to ${target_dir}. Try: sudo sh install.sh"
    fi

    INSTALLED_PATH="${target_dir}/bird"

    case ":${PATH}:" in
        *":${target_dir}:"*) NEEDS_PATH_HELP="false" ;;
        *) NEEDS_PATH_HELP="true" ;;
    esac
}

print_success() {
    target_dir="$(dirname "$INSTALLED_PATH")"
    printf '\n'
    success "${BOLD}Bird CLI v${VERSION} installed successfully!${RESET}"
    printf '\n'
    info "Installed to ${INSTALLED_PATH}"
    printf '\n'

    if [ "$NEEDS_PATH_HELP" = "true" ]; then
        warn "${target_dir} is not in your PATH"
        printf '\n'
        rc_file="$(shell_rc_file)"
        export_cmd="$(path_export_cmd "$target_dir")"
        printf '%s\n' "Add to your PATH by running:"
        printf '\n'
        printf '%s\n' "  ${CYAN}${export_cmd}${RESET}"
        printf '\n'
        printf '%s\n' "To make it permanent, add the line above to ${DIM}~/${rc_file}${RESET}"
        printf '\n'
    fi

    printf '%s\n' "Get started: ${CYAN}bird --help${RESET}"
}

# Source guard: only run main when executed directly, not when sourced.
if [ "${BIRD_CLI_SOURCED:-}" != "1" ]; then
    main "$@"
fi
