#!/bin/bash

# Graphorama Homebrew Formula Auto-Updater
# Updates the Homebrew formula with new release information

set -euo pipefail

VERSION="1.0.0"
SCRIPT_NAME=$(basename "$0")

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

# Configuration
GITHUB_REPO="nedops/grapharoma-mcp"
HOMEBREW_TAP_REPO="nedops/homebrew-tap"
FORMULA_NAME="graphorama"

# Print functions
print_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
print_success() { echo -e "${GREEN}[✅ SUCCESS]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[⚠️  WARN]${NC} $1"; }
print_error() { echo -e "${RED}[❌ ERROR]${NC} $1" >&2; }
print_bold() { echo -e "${BOLD}$1${NC}"; }

# Help function
show_help() {
cat << EOF
$SCRIPT_NAME v$VERSION - Homebrew Formula Auto-Updater

DESCRIPTION:
    Automatically updates the Homebrew formula for Graphorama with new release
    information including version, URLs, and SHA256 checksums.

USAGE:
    $SCRIPT_NAME [OPTIONS] <VERSION>

OPTIONS:
    -d, --dry-run           Show what would be updated without making changes
    -f, --force             Force update even if version exists
    -t, --tap-repo REPO     Homebrew tap repository (default: $HOMEBREW_TAP_REPO)
    -p, --push              Automatically push changes to tap repository
    -v, --verbose           Enable verbose output
    -h, --help              Show this help message
    --version               Show version information

ARGUMENTS:
    VERSION                 Version to update to (e.g., 0.1.0, v0.1.0)

EXAMPLES:
    # Update formula to version 0.1.0
    $SCRIPT_NAME 0.1.0

    # Dry run to see what would be updated
    $SCRIPT_NAME --dry-run 0.1.0

    # Update and push to custom tap
    $SCRIPT_NAME --tap-repo myuser/homebrew-tools --push 0.1.0

    # Force update existing version
    $SCRIPT_NAME --force 0.1.0

WHAT IT DOES:
    1. Validates the new version exists on GitHub releases
    2. Downloads release artifacts and calculates SHA256 checksums
    3. Updates the formula file with new version and checksums
    4. Optionally commits and pushes changes to the tap repository
    5. Validates the updated formula works with 'brew install --build-from-source'

REQUIREMENTS:
    - curl (for downloading release artifacts)
    - shasum (for calculating checksums)
    - git (for tap repository management)
    - brew (for formula validation, optional)
EOF
}

# Parse command line arguments
parse_args() {
    DRY_RUN=false
    FORCE=false
    PUSH=false
    VERBOSE=false
    TAP_REPO="$HOMEBREW_TAP_REPO"
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            -d|--dry-run)
                DRY_RUN=true
                shift
                ;;
            -f|--force)
                FORCE=true
                shift
                ;;
            -t|--tap-repo)
                TAP_REPO="$2"
                shift 2
                ;;
            -p|--push)
                PUSH=true
                shift
                ;;
            -v|--verbose)
                VERBOSE=true
                shift
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            --version)
                echo "$SCRIPT_NAME v$VERSION"
                exit 0
                ;;
            -*)
                print_error "Unknown option: $1"
                echo "Use --help for usage information."
                exit 1
                ;;
            *)
                # First non-option argument is the version
                if [[ -z "${NEW_VERSION:-}" ]]; then
                    NEW_VERSION="$1"
                else
                    print_error "Multiple versions specified: $NEW_VERSION and $1"
                    exit 1
                fi
                shift
                ;;
        esac
    done
    
    if [[ -z "${NEW_VERSION:-}" ]]; then
        print_error "Version is required"
        echo "Use --help for usage information."
        exit 1
    fi
    
    # Clean version (remove 'v' prefix if present)
    NEW_VERSION="${NEW_VERSION#v}"
}

# Verbose logging
log_verbose() {
    if [[ "$VERBOSE" == true ]]; then
        print_info "$1"
    fi
}

# Check if a command exists
check_command() {
    if ! command -v "$1" >/dev/null 2>&1; then
        print_error "Required command not found: $1"
        exit 1
    fi
}

# Validate release exists on GitHub
validate_release() {
    local version="$1"
    
    print_info "Validating release v$version exists on GitHub..."
    
    local release_url="https://api.github.com/repos/$GITHUB_REPO/releases/tags/v$version"
    local response
    
    if ! response=$(curl -s -f "$release_url"); then
        print_error "Release v$version not found on GitHub"
        print_error "Make sure the release exists: https://github.com/$GITHUB_REPO/releases/tag/v$version"
        exit 1
    fi
    
    log_verbose "Release v$version found on GitHub"
    
    # Check if release has the required assets
    local required_assets=(
        "graphorama-x86_64-apple-darwin.tar.gz"
        "graphorama-aarch64-apple-darwin.tar.gz"
        "graphorama-x86_64-unknown-linux-gnu.tar.gz"
        "graphorama-aarch64-unknown-linux-gnu.tar.gz"
    )
    
    for asset in "${required_assets[@]}"; do
        if ! echo "$response" | grep -q "\"name\": \"$asset\""; then
            print_warning "Release asset not found: $asset"
        else
            log_verbose "Found asset: $asset"
        fi
    done
}

# Download asset and calculate SHA256
get_asset_sha256() {
    local version="$1"
    local asset_name="$2"
    local download_url="https://github.com/$GITHUB_REPO/releases/download/v$version/$asset_name"
    
    log_verbose "Downloading $asset_name for checksum calculation..."
    
    local temp_file
    temp_file=$(mktemp)
    
    if curl -sL -f "$download_url" -o "$temp_file"; then
        local sha256
        sha256=$(shasum -a 256 "$temp_file" | cut -d' ' -f1)
        rm -f "$temp_file"
        echo "$sha256"
    else
        rm -f "$temp_file"
        print_warning "Failed to download $asset_name, using placeholder checksum"
        echo "0000000000000000000000000000000000000000000000000000000000000000"
    fi
}

# Update formula file
update_formula() {
    local version="$1"
    local formula_file="$2"
    
    if [[ ! -f "$formula_file" ]]; then
        print_error "Formula file not found: $formula_file"
        exit 1
    fi
    
    print_info "Calculating checksums for release v$version..."
    
    # Get checksums for each platform
    local sha_mac_arm sha_mac_intel sha_linux_x64 sha_linux_arm
    
    sha_mac_arm=$(get_asset_sha256 "$version" "graphorama-aarch64-apple-darwin.tar.gz")
    sha_mac_intel=$(get_asset_sha256 "$version" "graphorama-x86_64-apple-darwin.tar.gz")
    sha_linux_x64=$(get_asset_sha256 "$version" "graphorama-x86_64-unknown-linux-gnu.tar.gz")
    sha_linux_arm=$(get_asset_sha256 "$version" "graphorama-aarch64-unknown-linux-gnu.tar.gz")
    
    print_info "Updating formula file..."
    
    if [[ "$DRY_RUN" == true ]]; then
        print_info "DRY RUN - Would update:"
        echo "  Version: $version"
        echo "  macOS ARM64 SHA256: $sha_mac_arm"
        echo "  macOS Intel SHA256: $sha_mac_intel"
        echo "  Linux x64 SHA256: $sha_linux_x64"
        echo "  Linux ARM64 SHA256: $sha_linux_arm"
        return 0
    fi
    
    # Create backup
    cp "$formula_file" "$formula_file.backup"
    
    # Update version and checksums using Ruby template
    create_updated_formula "$version" "$sha_mac_arm" "$sha_mac_intel" "$sha_linux_x64" "$sha_linux_arm" > "$formula_file.new"
    
    # Replace original file
    mv "$formula_file.new" "$formula_file"
    
    print_success "Formula updated to version $version"
}

# Create updated formula with proper checksums
create_updated_formula() {
    local version="$1"
    local sha_mac_arm="$2"
    local sha_mac_intel="$3"
    local sha_linux_x64="$4"
    local sha_linux_arm="$5"
    
    cat << EOF
# Homebrew Formula for Graphorama MCP Server
class Graphorama < Formula
  desc "High-performance MCP server for code validation and service orchestration"
  homepage "https://github.com/$GITHUB_REPO"
  license "MIT"

  # Release information - automatically updated by CI
  version "$version"
  
  # Platform-specific URLs and checksums
  if OS.mac?
    if Hardware::CPU.arm?
      url "https://github.com/$GITHUB_REPO/releases/download/v#{version}/graphorama-aarch64-apple-darwin.tar.gz"
      sha256 "$sha_mac_arm"
    else
      url "https://github.com/$GITHUB_REPO/releases/download/v#{version}/graphorama-x86_64-apple-darwin.tar.gz"
      sha256 "$sha_mac_intel"
    end
  elsif OS.linux?
    if Hardware::CPU.arm?
      url "https://github.com/$GITHUB_REPO/releases/download/v#{version}/graphorama-aarch64-unknown-linux-gnu.tar.gz"
      sha256 "$sha_linux_arm"
    else
      url "https://github.com/$GITHUB_REPO/releases/download/v#{version}/graphorama-x86_64-unknown-linux-gnu.tar.gz"
      sha256 "$sha_linux_x64"
    end
  end

  # No dependencies - single binary deployment
  # Optional runtime dependencies for enhanced features
  depends_on "redis" => :optional
  depends_on "docker" => :optional
  depends_on "kubernetes-cli" => :optional

  def install
    # Install the binary
    bin.install "graphorama"

    # Create configuration directory
    (etc/"graphorama").mkpath

    # Install default configuration
    (etc/"graphorama/graphorama.toml").write default_config

    # Install completion scripts
    generate_completions_from_executable(bin/"graphorama", "completion")
  end

  def post_install
    # Create cache directory
    (var/"cache/graphorama").mkpath

    # Create log directory  
    (var/"log/graphorama").mkpath

    # Set appropriate permissions
    chmod 0755, var/"cache/graphorama"
    chmod 0755, var/"log/graphorama"
  end

  service do
    run [opt_bin/"graphorama", "serve", "--transport", "stdio", "--config", etc/"graphorama/graphorama.toml"]
    environment_variables PATH: std_service_path_env
    keep_alive false
    log_path var/"log/graphorama/graphorama.log"
    error_log_path var/"log/graphorama/graphorama-error.log"
  end

  test do
    # Test basic functionality
    assert_match version.to_s, shell_output("#{bin}/graphorama --version")
    
    # Test configuration validation
    assert_match "Configuration loaded", shell_output("#{bin}/graphorama config --validate 2>&1", 0)
    
    # Test MCP tools list (should not hang)
    output = shell_output("timeout 5s #{bin}/graphorama serve --transport stdio < /dev/null 2>&1 || true")
    assert_match(/tools|error/, output)
  end

  def caveats
    <<~EOS
      🚀 Graphorama MCP Server installed successfully!

      📁 Configuration:
         Config file: #{etc}/graphorama/graphorama.toml
         Cache dir:   #{var}/cache/graphorama
         Logs dir:    #{var}/log/graphorama

      🔧 Quick Setup:
         # Test installation
         graphorama --version
         graphorama doctor

         # Configure for Claude Desktop
         graphorama init --platform claude-desktop

         # Start MCP server
         graphorama serve --transport stdio

      📚 Platform-specific guides available at:
         https://github.com/$GITHUB_REPO/tree/main/docs/quick-start

      💡 To enable service management:
         brew services start graphorama
         brew services stop graphorama

      🎯 MCP Tools Available:
         - validate_changes    - Code validation with caching
         - discover_services   - Multi-source service discovery  
         - validate_cross_service - Breaking change detection
         - run_integration_tests - Test orchestration
         - get_cache_stats     - Performance metrics
         - watch_path          - File monitoring
         - validate_contract   - API contract validation
    EOS
  end

  private

  def default_config
    <<~TOML
      # Graphorama MCP Server Configuration
      # Generated by Homebrew installation

      [validation]
      languages = ["rust", "python", "javascript", "typescript", "go", "java"]
      auto_run_tests = false
      max_file_size = 10485760  # 10MB
      timeout_seconds = 30

      [cache]
      backend = "memory"  # Options: memory, sqlite, redis
      ttl_seconds = 300
      max_size_mb = 100
      # For sqlite backend:
      # sqlite_path = "#{var}/cache/graphorama/cache.db"
      # For redis backend:
      # redis_url = "redis://localhost:6379"

      [discovery]
      sources = ["process"]  # Options: docker, kubernetes, process
      include_health = false
      timeout_seconds = 10

      [logging]
      level = "info"
      file = "#{var}/log/graphorama/graphorama.log"
      max_size_mb = 50
      max_files = 5

      [server]
      # bind_address = "127.0.0.1"
      # port = 3000
    TOML
  end
end
EOF
}

# Main execution
main() {
    print_bold "🍺 Homebrew Formula Auto-Updater v$VERSION"
    echo
    
    # Parse arguments
    parse_args "$@"
    
    # Check required commands
    check_command curl
    check_command shasum
    
    print_info "Updating $FORMULA_NAME formula to version $NEW_VERSION"
    echo
    
    # Determine formula file location
    local formula_file
    if [[ -f "$FORMULA_NAME.rb" ]]; then
        # Local formula file
        formula_file="$FORMULA_NAME.rb"
        print_info "Using local formula file: $formula_file"
    else
        print_error "Formula file not found: $FORMULA_NAME.rb"
        print_error "This script should be run from the repository root"
        exit 1
    fi
    
    # Validate release exists and update formula
    validate_release "$NEW_VERSION"
    update_formula "$NEW_VERSION" "$formula_file"
    
    echo
    print_success "Formula update complete!"
    echo
    print_info "Next steps:"
    echo "  1. Test the formula: brew install --build-from-source ./$FORMULA_NAME.rb"
    echo "  2. Create a tap: Create repository 'homebrew-tap' on GitHub"
    echo "  3. Add formula to tap: Copy $FORMULA_NAME.rb to the tap repository"
    echo "  4. Use with: brew tap $HOMEBREW_TAP_REPO && brew install $FORMULA_NAME"
    echo
}

# Run main function
main "$@"