#!/bin/bash
# Fabric Installer Script
# Usage: curl -fsSL https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.sh | bash
# Usage with custom directory: curl -fsSL https://raw.githubusercontent.com/danielmiessler/fabric/main/scripts/installer/install.sh | INSTALL_DIR=/usr/local/bin bash

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Print functions
print_info() {
    printf "${BLUE}[INFO]${NC} %s\n" "$1"
}

print_success() {
    printf "${GREEN}[SUCCESS]${NC} %s\n" "$1"
}

print_warning() {
    printf "${YELLOW}[WARNING]${NC} %s\n" "$1"
}

print_error() {
    printf "${RED}[ERROR]${NC} %s\n" "$1" >&2
}

# Detect OS
detect_os() {
    case "$(uname -s)" in
        Darwin*)
            echo "Darwin"
            ;;
        Linux*)
            echo "Linux"
            ;;
        *)
            print_error "Unsupported operating system: $(uname -s)"
            print_error "This installer only supports Darwin (macOS) and Linux"
            exit 1
            ;;
    esac
}

# Detect architecture
detect_arch() {
    case "$(uname -m)" in
        x86_64|amd64)
            echo "x86_64"
            ;;
        arm64|aarch64)
            echo "arm64"
            ;;
        *)
            print_error "Unsupported architecture: $(uname -m)"
            print_error "This installer only supports x86_64 and arm64"
            exit 1
            ;;
    esac
}

# Check if command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Download and extract fabric
install_fabric() {
    local os="$1"
    local arch="$2"
    local install_dir="$3"

    # Construct download URL
    local filename="fabric_${os}_${arch}.tar.gz"
    local download_url="https://github.com/danielmiessler/fabric/releases/latest/download/${filename}"

    print_info "Downloading Fabric for ${os} ${arch}..."
    print_info "URL: ${download_url}"

    # Create temporary directory
    local temp_dir
    temp_dir=$(mktemp -d)
    local temp_file="${temp_dir}/fabric.tar.gz"

    # Download the archive
    if command_exists curl; then
        if ! curl -fsSL "${download_url}" -o "${temp_file}"; then
            print_error "Failed to download Fabric"
            rm -rf "${temp_dir}"
            exit 1
        fi
    elif command_exists wget; then
        if ! wget -q "${download_url}" -O "${temp_file}"; then
            print_error "Failed to download Fabric"
            rm -rf "${temp_dir}"
            exit 1
        fi
    else
        print_error "Neither curl nor wget found. Please install one of them and try again."
        exit 1
    fi

    print_info "Extracting Fabric binary..."

    # Extract only the fabric binary from the archive
    if ! tar -xzf "${temp_file}" -C "${temp_dir}" fabric; then
        print_error "Failed to extract Fabric binary"
        rm -rf "${temp_dir}"
        exit 1
    fi

    # Create install directory if it doesn't exist
    if [ ! -d "${install_dir}" ]; then
        print_info "Creating install directory: ${install_dir}"
        if ! mkdir -p "${install_dir}"; then
            print_error "Failed to create install directory: ${install_dir}"
            print_error "You may need to run with sudo or choose a different directory"
            rm -rf "${temp_dir}"
            exit 1
        fi
    fi

    # Move binary to install directory
    print_info "Installing Fabric to ${install_dir}/fabric..."
    if ! mv "${temp_dir}/fabric" "${install_dir}/fabric"; then
        print_error "Failed to install Fabric to ${install_dir}"
        print_error "You may need to run with sudo or choose a different directory"
        rm -rf "${temp_dir}"
        exit 1
    fi

    # Make sure it's executable
    chmod +x "${install_dir}/fabric"

    # Clean up
    rm -rf "${temp_dir}"

    print_success "Fabric installed successfully to ${install_dir}/fabric"
}

# Check PATH and provide instructions
check_path() {
    local install_dir="$1"

    if echo "$PATH" | grep -q "${install_dir}"; then
        print_success "✅ ${install_dir} is already in your PATH"
    else
        print_warning "⚠️  ${install_dir} is not in your PATH"
        print_info "To use fabric from anywhere, add the following to your shell profile:"
        print_info "  export PATH=\"\$PATH:${install_dir}\""
        print_info ""
        print_info "For bash, add it to ~/.bashrc or ~/.bash_profile"
        print_info "For zsh, add it to ~/.zshrc"
        print_info "For fish, run: fish_add_path ${install_dir}"
    fi
}

# Verify installation
verify_installation() {
    local install_dir="$1"
    local fabric_path="${install_dir}/fabric"

    if [ -x "${fabric_path}" ]; then
        print_info "Verifying installation..."
        local version
        if version=$("${fabric_path}" --version 2>/dev/null); then
            print_success "Fabric ${version} is working correctly!"
        else
            print_warning "Fabric binary exists but --version failed"
        fi
    else
        print_error "Fabric binary not found at ${fabric_path}"
        exit 1
    fi
}

# Main installation function
main() {
    print_info "🚀 Starting Fabric installation..."

    # Detect system
    local os
    local arch
    os=$(detect_os)
    arch=$(detect_arch)

    print_info "Detected system: ${os} ${arch}"

    # Determine install directory
    local install_dir="${INSTALL_DIR:-${HOME}/.local/bin}"

    print_info "Install directory: ${install_dir}"

    # Install fabric
    install_fabric "${os}" "${arch}" "${install_dir}"

    # Verify installation
    verify_installation "${install_dir}"

    # Check PATH
    check_path "${install_dir}"

    print_info ""
    print_success "🎉 Installation complete!"
    print_info ""
    print_info "Next steps:"
    print_info "  1. Run 'fabric --setup' to configure Fabric"
    print_info "  2. Add your API keys and preferences"
    print_info "  3. Start using Fabric with 'fabric --help'"
    print_info ""
    print_info "Documentation: https://github.com/danielmiessler/fabric"
}

# Run main function
main "$@"