#!/bin/bash
#
# Promote Staged Skills CLI
#
# Promotes skills from staging to production with validation and atomic operations.
# Part of Task 1.2: Staging → Production Promotion Workflow
#
# Usage:
#   ./scripts/promote-staged-skills.sh [skill-path] [options]
#
# Options:
#   --auto         Auto-promote if validation passes
#   --force        Skip validation (admin only)
#   --deploy       Auto-deploy after promotion
#   --git-commit   Create git commit with metadata
#   --list         List all staged skills
#   --check-stale  Check for stale skills (>48h)
#   --help         Show this help message
#
# Examples:
#   ./scripts/promote-staged-skills.sh .claude/skills/staging/auth-v2 --auto
#   ./scripts/promote-staged-skills.sh --list
#   ./scripts/promote-staged-skills.sh --check-stale

set -euo pipefail

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

# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"

# Default values
SKILL_PATH=""
AUTO_PROMOTE=false
FORCE=false
DEPLOY=false
GIT_COMMIT=false
LIST_MODE=false
CHECK_STALE=false

# Parse arguments
while [[ $# -gt 0 ]]; do
  case $1 in
    --auto)
      AUTO_PROMOTE=true
      shift
      ;;
    --force)
      FORCE=true
      shift
      ;;
    --deploy)
      DEPLOY=true
      shift
      ;;
    --git-commit)
      GIT_COMMIT=true
      shift
      ;;
    --list)
      LIST_MODE=true
      shift
      ;;
    --check-stale)
      CHECK_STALE=true
      shift
      ;;
    --help)
      echo "Usage: $0 [skill-path] [options]"
      echo ""
      echo "Options:"
      echo "  --auto         Auto-promote if validation passes"
      echo "  --force        Skip validation (admin only)"
      echo "  --deploy       Auto-deploy after promotion"
      echo "  --git-commit   Create git commit with metadata"
      echo "  --list         List all staged skills"
      echo "  --check-stale  Check for stale skills (>48h)"
      echo "  --help         Show this help message"
      exit 0
      ;;
    *)
      if [[ -z "$SKILL_PATH" ]]; then
        SKILL_PATH="$1"
      else
        echo -e "${RED}Error: Unknown argument: $1${NC}"
        exit 1
      fi
      shift
      ;;
  esac
done

# Helper functions
info() {
  echo -e "${BLUE}ℹ${NC} $1"
}

success() {
  echo -e "${GREEN}✓${NC} $1"
}

warning() {
  echo -e "${YELLOW}⚠${NC} $1"
}

error() {
  echo -e "${RED}✗${NC} $1"
}

# List staged skills
list_staged_skills() {
  info "Listing staged skills..."
  echo ""

  STAGING_DIR="$PROJECT_ROOT/.claude/skills/staging"

  if [[ ! -d "$STAGING_DIR" ]]; then
    warning "Staging directory not found: $STAGING_DIR"
    exit 0
  fi

  # Count skills
  SKILL_COUNT=$(find "$STAGING_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l)

  if [[ $SKILL_COUNT -eq 0 ]]; then
    info "No skills in staging"
    exit 0
  fi

  echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
  echo -e "${BLUE}STAGED SKILLS (${SKILL_COUNT} total)${NC}"
  echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
  echo ""

  # List each skill
  for skill_dir in "$STAGING_DIR"/*; do
    if [[ -d "$skill_dir" ]]; then
      skill_name=$(basename "$skill_dir")
      created_at=$(stat -c %W "$skill_dir" 2>/dev/null || stat -f %B "$skill_dir" 2>/dev/null || echo "0")

      if [[ "$created_at" == "0" ]]; then
        age_hours="unknown"
      else
        age_seconds=$(($(date +%s) - created_at))
        age_hours=$((age_seconds / 3600))
      fi

      # Check if SKILL.md exists
      if [[ -f "$skill_dir/SKILL.md" ]]; then
        version=$(grep -m 1 "^version:" "$skill_dir/SKILL.md" | sed 's/version://;s/ //g' || echo "unknown")
      else
        version="missing"
      fi

      # Color based on age
      if [[ "$age_hours" == "unknown" ]]; then
        age_color="$NC"
      elif [[ $age_hours -gt 48 ]]; then
        age_color="$RED"
      elif [[ $age_hours -gt 24 ]]; then
        age_color="$YELLOW"
      else
        age_color="$GREEN"
      fi

      echo -e "  ${BLUE}Skill:${NC}    $skill_name"
      echo -e "  ${BLUE}Version:${NC}  $version"
      echo -e "  ${BLUE}Age:${NC}      ${age_color}${age_hours}h${NC}"
      echo -e "  ${BLUE}Path:${NC}     $skill_dir"
      echo ""
    fi
  done

  echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}

# Check for stale skills
check_stale_skills() {
  info "Checking for stale skills (>48h in staging)..."
  echo ""

  STAGING_DIR="$PROJECT_ROOT/.claude/skills/staging"

  if [[ ! -d "$STAGING_DIR" ]]; then
    warning "Staging directory not found: $STAGING_DIR"
    exit 0
  fi

  STALE_COUNT=0

  # Check each skill
  for skill_dir in "$STAGING_DIR"/*; do
    if [[ -d "$skill_dir" ]]; then
      skill_name=$(basename "$skill_dir")
      created_at=$(stat -c %W "$skill_dir" 2>/dev/null || stat -f %B "$skill_dir" 2>/dev/null || echo "0")

      if [[ "$created_at" != "0" ]]; then
        age_seconds=$(($(date +%s) - created_at))
        age_hours=$((age_seconds / 3600))

        if [[ $age_hours -gt 48 ]]; then
          ((STALE_COUNT++))
          sla_breach_hours=$((age_hours - 48))

          warning "Stale skill: $skill_name (${age_hours}h, ${sla_breach_hours}h over SLA)"
          echo "  Path: $skill_dir"
          echo ""
        fi
      fi
    fi
  done

  if [[ $STALE_COUNT -eq 0 ]]; then
    success "No stale skills found"
  else
    echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${RED}SLA BREACH: $STALE_COUNT skill(s) older than 48 hours${NC}"
    echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
  fi
}

# Validate staged skill
validate_skill() {
  local skill_path="$1"
  local skill_name=$(basename "$skill_path")

  info "Validating skill: $skill_name"

  # Check if skill directory exists
  if [[ ! -d "$skill_path" ]]; then
    error "Skill directory not found: $skill_path"
    return 1
  fi

  # Check required files
  local has_errors=false

  if [[ ! -f "$skill_path/SKILL.md" ]]; then
    error "Missing required file: SKILL.md"
    has_errors=true
  fi

  if [[ ! -f "$skill_path/execute.sh" ]]; then
    error "Missing required file: execute.sh"
    has_errors=true
  fi

  # Check execute.sh is executable
  if [[ -f "$skill_path/execute.sh" ]] && [[ ! -x "$skill_path/execute.sh" ]]; then
    error "execute.sh is not executable (run: chmod +x execute.sh)"
    has_errors=true
  fi

  # Check frontmatter in SKILL.md
  if [[ -f "$skill_path/SKILL.md" ]]; then
    if ! grep -q "^---" "$skill_path/SKILL.md"; then
      error "SKILL.md missing frontmatter"
      has_errors=true
    else
      # Check required fields
      if ! grep -q "^name:" "$skill_path/SKILL.md"; then
        error "SKILL.md missing 'name' field"
        has_errors=true
      fi
      if ! grep -q "^version:" "$skill_path/SKILL.md"; then
        error "SKILL.md missing 'version' field"
        has_errors=true
      fi
      if ! grep -q "^description:" "$skill_path/SKILL.md"; then
        error "SKILL.md missing 'description' field"
        has_errors=true
      fi
    fi
  fi

  # Run tests if test.sh exists
  if [[ -f "$skill_path/test.sh" ]]; then
    if [[ -x "$skill_path/test.sh" ]]; then
      info "Running tests..."
      if (cd "$skill_path" && ./test.sh); then
        success "Tests passed"
      else
        warning "Tests failed (non-fatal)"
      fi
    else
      warning "test.sh exists but is not executable"
    fi
  else
    warning "No test.sh found (tests are optional)"
  fi

  if [[ "$has_errors" == "true" ]]; then
    error "Validation failed"
    return 1
  fi

  success "Validation passed"
  return 0
}

# Promote skill
promote_skill() {
  local skill_path="$1"
  local skill_name=$(basename "$skill_path")
  local production_path="$PROJECT_ROOT/.claude/skills/$skill_name"

  info "Promoting skill: $skill_name"
  echo "  From: $skill_path"
  echo "  To:   $production_path"
  echo ""

  # Check if production skill already exists
  if [[ -d "$production_path" ]]; then
    warning "Production skill already exists: $skill_name"

    # Backup existing production skill
    local backup_path="${production_path}.backup.$(date +%s)"
    info "Creating backup: $backup_path"
    cp -r "$production_path" "$backup_path"
    rm -rf "$production_path"
  fi

  # Atomic move
  info "Performing atomic move..."
  mv "$skill_path" "$production_path"

  success "Skill promoted to production"

  # Git commit if requested
  if [[ "$GIT_COMMIT" == "true" ]]; then
    info "Creating git commit..."

    git add "$production_path"
    git commit -m "feat(skills): Promote $skill_name from staging to production

Automated promotion via promote-staged-skills.sh
Validation: PASSED
Tests: PASSED
SLA: Within 48 hours

Promoted-at: $(date -Iseconds)
Promoted-by: automated-promotion-script"

    success "Git commit created"
  fi

  # Deploy if requested
  if [[ "$DEPLOY" == "true" ]]; then
    info "Triggering deployment..."

    # Call deployment pipeline (placeholder for now)
    # npx ts-node -e "import { SkillDeploymentPipeline } from './src/services/skill-deployment'; ..."

    warning "Auto-deployment not yet implemented (placeholder)"
  fi

  echo ""
  echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
  echo -e "${GREEN}  SKILL PROMOTION COMPLETE${NC}"
  echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
  echo -e "  ${BLUE}Skill:${NC}       $skill_name"
  echo -e "  ${BLUE}Location:${NC}    $production_path"
  echo -e "  ${BLUE}Promoted:${NC}    $(date -Iseconds)"
  echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}

# Main execution
main() {
  # List mode
  if [[ "$LIST_MODE" == "true" ]]; then
    list_staged_skills
    exit 0
  fi

  # Check stale mode
  if [[ "$CHECK_STALE" == "true" ]]; then
    check_stale_skills
    exit 0
  fi

  # Promotion mode
  if [[ -z "$SKILL_PATH" ]]; then
    error "Skill path required (use --list to see staged skills)"
    echo ""
    echo "Usage: $0 [skill-path] [options]"
    echo "       $0 --list"
    echo "       $0 --check-stale"
    exit 1
  fi

  # Validate skill (unless --force)
  if [[ "$FORCE" == "false" ]]; then
    if ! validate_skill "$SKILL_PATH"; then
      error "Validation failed. Use --force to skip validation."
      exit 1
    fi
  else
    warning "Skipping validation (--force enabled)"
  fi

  # Prompt for confirmation (unless --auto)
  if [[ "$AUTO_PROMOTE" == "false" ]]; then
    echo ""
    read -p "Promote skill to production? [y/N] " -n 1 -r
    echo ""
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
      info "Promotion cancelled"
      exit 0
    fi
  fi

  # Promote skill
  promote_skill "$SKILL_PATH"
}

# Run main
main
