#!/bin/bash
set -e

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

# Logging functions
log_info() { echo -e "${BLUE}[INFO]${NC} $1" >&2; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" >&2; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" >&2; }
log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }

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

# Lightweight JSON URL extractor using grep and sed (no jq/python)
parse_and_select_url() {
    local response="$1"
    local target_os="$2"
    local target_arch="$3"
    
    local obj_os obj_arch obj_url
    local found_url=""
    local tmpfile="/tmp/codearts_parse_$$"
    
    echo "$response" | grep -oE '\{"os"[^}]*\}' > "$tmpfile"
    
    while read -r obj; do
        obj_os=$(echo "$obj" | grep -oE '"os"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"\([^"]*\)"$/\1/')
        obj_arch=$(echo "$obj" | grep -oE '"arch"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"\([^"]*\)"$/\1/')
        obj_url=$(echo "$obj" | grep -oE '"url"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"\([^"]*\)"$/\1/')
        
        if [ "$obj_os" = "$target_os" ] && [ "$obj_arch" = "$target_arch" ] && [ -n "$obj_url" ]; then
            found_url="$obj_url"
            break
        fi
    done < "$tmpfile"
    
    rm -f "$tmpfile"
    
    if [ -n "$found_url" ]; then
        echo "$found_url"
        return 0
    fi
    return 1
}
# Install binary
install_binary() {
    # Detect OS and architecture using the improved logic
    local raw_os=$(uname -s)
    local os=$(echo "$raw_os" | tr '[:upper:]' '[:lower:]')
    case "$raw_os" in
        Darwin*) os="darwin" ;;
        Linux*) os="linux" ;;
        MINGW*|MSYS*|CYGWIN*) 
            log_error "Windows is not supported by this installer."
            exit 1
            ;;
        *) 
            log_error "Unsupported OS: $raw_os"
            exit 1
            ;;
    esac

    local arch=$(uname -m)
    if [ "$arch" = "aarch64" ]; then
        arch="arm64"
    fi
    if [ "$arch" = "x86_64" ]; then
        arch="x64"
    fi

    # Rosetta detection for Darwin (if running x64 on arm64)
    if [ "$os" = "darwin" ] && [ "$arch" = "x64" ]; then
        rosetta_flag=$(sysctl -n sysctl.proc_translated 2>/dev/null || echo 0)
        if [ "$rosetta_flag" = "1" ]; then
            arch="arm64"
        fi
    fi

    # Validate combo
    local combo="$os-$arch"
    case "$combo" in
        linux-x64|linux-arm64|darwin-x64|darwin-arm64)
            ;;
        *)
            log_error "Unsupported OS/Arch: $os/$arch"
            exit 1
            ;;
    esac

    # Determine archive extension
    local archive_ext=".tar.gz"
    
    # Check for musl (Alpine/others)
    local is_musl=false
    if [ "$os" = "linux" ]; then
        if [ -f /etc/alpine-release ]; then
            is_musl=true
        fi
        if command -v ldd >/dev/null 2>&1; then
            if ldd --version 2>&1 | grep -qi musl; then
                is_musl=true
            fi
        fi
    fi

    # Check for AVX2 baseline requirement
    local needs_baseline=false
    if [ "$arch" = "x64" ]; then
        if [ "$os" = "linux" ]; then
            if ! grep -qwi avx2 /proc/cpuinfo 2>/dev/null; then
                needs_baseline=true
            fi
        fi
        if [ "$os" = "darwin" ]; then
            avx2=$(sysctl -n hw.optional.avx2_0 2>/dev/null || echo 0)
            if [ "$avx2" != "1" ]; then
                needs_baseline=true
            fi
        fi
    fi

    # Construct target based on detection
    local target="$arch"
    if [ "$needs_baseline" = "true" ]; then
        target="$target-baseline"
    fi
    if [ "$is_musl" = "true" ]; then
        target="$target-musl"
    fi

    # Set APP name
    local APP="codearts"

    log_info "Detected platform: $target"

    # Fetch the JSON info from the new endpoint
    log_info "Fetching release info from https://cnnorth4-cloudide-marketplace.obs.cn-north-4.myhuaweicloud.com/codearts/cli_tui/install_script/codearts_cli_versioninfo_v1.0.json ..."
    
    local json_response
    if ! json_response=$(curl -fsSL "https://cnnorth4-cloudide-marketplace.obs.cn-north-4.myhuaweicloud.com/codearts/cli_tui/install_script/codearts_cli_versioninfo_v1.0.json"); then
        log_error "Failed to fetch release information from the server."
        exit 1
    fi

    # Extract the correct URL using pure Bash parser
    local download_url
    download_url=$(parse_and_select_url "$json_response" "$os" "$target")

    # Check if the URL was found
    if [ -z "$download_url" ]; then
        log_error "No valid download URL found for your platform: $os / $target"
        log_info "Please check if your architecture is supported in the response."
        exit 1
    fi

    log_info "Matched Download URL: $download_url"

    # Get the filename from the URL (last part after /)
    local filename
    filename=$(basename "$download_url")
    if [ -z "$filename" ]; then
        filename="${APP}-${target}.tar.gz"
    fi

    local tmp_file="/tmp/$filename"

    # Download
    log_info "Downloading $APP ($target)..."
    if ! curl -fsSL -o "$tmp_file" "$download_url"; then
        log_error "Download failed. Please check your network or the URL."
        rm -f "$tmp_file"
        return 1
    fi

    # New installation directories
    local base_dir="$HOME/.codeartsdoer/installers"
    local bin_dir="$base_dir/bin"

    # Extract 
    rm -rf "$base_dir-new"
    mkdir -p "$base_dir-new/bin"

    if ! tar -C "$base_dir-new" -xzf "$tmp_file"; then
        log_error "Failed to extract archive"
        rm -f "$tmp_file"
        return 1
    fi

    # Replace old installation
    rm -rf "$base_dir"
    mv "$base_dir-new" "$base_dir"
    rm -f "$tmp_file"

    # Handle specific files inside the extracted package
    # 1. Move and rename agentkernel to codearts executable
    if [ -f "$base_dir/agentkernel" ]; then
        mv "$base_dir/agentkernel" "$bin_dir/codearts"
        chmod +x "$bin_dir/codearts"
        log_success "Executable 'agentkernel' installed to $bin_dir/codearts"
    else
        log_error "Expected executable 'agentkernel' not found in the archive!"
        return 1
    fi

    # 2. Ensure startup script 'codearts' is in the base directory
    if [ -f "$base_dir/codearts" ]; then
        chmod +x "$base_dir/codearts"
        log_success "Startup script 'codearts' installed to $base_dir/codearts"
    else
        log_error "Expected startup script 'codearts' not found in the archive!"
        return 1
    fi

    # Only add the base directory to PATH (bin directory is intentionally excluded)
    add_to_path "$base_dir"

    # Create permission directory and config
    local permission_dir="$HOME/.codeartsdoer/cli-data/storage/permission"
    local permission_config="$permission_dir/config.json"
    mkdir -p "$permission_dir"
    if [ ! -f "$permission_config" ]; then
        echo '{"bash_mode": "sandbox"}' > "$permission_config"
    fi

    # Create sandbox directory and config
    local sandbox_dir="$HOME/.codeartsdoer/cli-data/storage/sandbox"
    local sandbox_config="$sandbox_dir/config.json"
    mkdir -p "$sandbox_dir"
    if [ ! -f "$sandbox_config" ]; then
        echo '{"network_policy": "deny_all"}' > "$sandbox_config"
    fi
}

# Add directory to PATH
add_to_path() {
    local dir="$1"

    # Check if already in PATH
    if echo "$PATH" | grep -q "$dir"; then
        log_info "$dir is already in PATH"
        return 0
    fi

    # Determine shell profile based on user's shell
    local profile
    local is_fish=false
    case "$SHELL" in
        */zsh)
            profile="$HOME/.zshrc"
            ;;
        */bash)
            if [ -f "$HOME/.bash_profile" ]; then
                profile="$HOME/.bash_profile"
            else
                profile="$HOME/.bashrc"
            fi
            ;;
        */fish)
            profile="$HOME/.config/fish/config.fish"
            is_fish=true
            ;;
        *)
            profile="$HOME/.profile"
            ;;
    esac

    # Add to profile
    log_info "Adding $dir to PATH in $profile"
    mkdir -p "$(dirname "$profile")"
    echo "" >> "$profile"
    echo "# Added by codearts installer" >> "$profile"

    if [ "$is_fish" = true ]; then
        echo "fish_add_path $dir" >> "$profile"
    else
        echo "export PATH=\"$dir:\$PATH\"" >> "$profile"
    fi

    export PATH="$dir:$PATH"
    log_success "Added to PATH. Restart your shell or run: source $profile"
}

# Main
main() {
    log_info "Starting codearts installation..."

    # Install binary
    if ! install_binary; then
        log_error "Installation failed"
        exit 1
    fi

    # Verify installation
    if command_exists "codearts"; then
        log_success "codearts is now available! Version: $(codearts --version 2>/dev/null || echo "unknown")"
    else
        log_warning "codearts not found in current PATH. Please restart your shell."
    fi

    # 清理 sandbox_runner 目录
    local sandbox_runner_dir="$HOME/.codeartsdoer/cli-data/sandbox_runner"
    if [ -d "$sandbox_runner_dir" ]; then
        rm -rf "$sandbox_runner_dir"
    fi
}

main "$@"
