#!/bin/bash
# modules/validation.sh - Validation functions

# Check if all required dependencies are installed
function check_dependencies() {
  local missing_deps=()
  
  echo "${STATUS_SCAN} Checking dependencies..."
  
  if ! command -v aws >/dev/null 2>&1; then
    missing_deps+=("aws-cli")
  else
    # Check AWS credentials
    if ! aws sts get-caller-identity >/dev/null 2>&1; then
      local fix_instructions="   → Run: aws configure
   → Or set environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
   → Or use AWS IAM roles/instance profiles"
      
      if wait_for_user_action \
        "AWS CLI found but credentials not configured" \
        "$fix_instructions" \
        "check_dependencies"; then
        return 0
      else
        print_warning "AWS credentials issue - deployments may fail until fixed"
        return 1
      fi
    fi
  fi
  
  if ! command -v git >/dev/null 2>&1; then
    missing_deps+=("git")
  else
    # Check if we're in a git repository
    if ! git rev-parse --git-dir >/dev/null 2>&1; then
      local fix_instructions="   → Initialize git repository:
      git init
      git add .
      git commit -m 'Initial commit'"
      
      if wait_for_user_action \
        "Not in a git repository" \
        "$fix_instructions" \
        "check_dependencies"; then
        return 0
      else
        print_warning "Git repository issue - deployments may fail until fixed"
        return 1
      fi
    fi
  fi
  
  if ! command -v zip >/dev/null 2>&1; then
    missing_deps+=("zip")
  fi
  
  if ! command -v fswatch >/dev/null 2>&1; then
    missing_deps+=("fswatch")
  fi
  
  if [[ ${#missing_deps[@]} -gt 0 ]]; then
    local fix_instructions="${STATUS_CONFIG} Installation instructions:"
    for dep in "${missing_deps[@]}"; do
      case "$dep" in
        "aws-cli")
          fix_instructions="$fix_instructions
   AWS CLI:
     macOS: brew install awscli
     Ubuntu: sudo apt-get install awscli
     Or: pip install awscli"
          ;;
        "git")
          fix_instructions="$fix_instructions
   Git:
     macOS: brew install git
     Ubuntu: sudo apt-get install git"
          ;;
        "zip")
          fix_instructions="$fix_instructions
   Zip:
     macOS: Already installed
     Ubuntu: sudo apt-get install zip"
          ;;
        "fswatch")
          fix_instructions="$fix_instructions
   fswatch:
     macOS: brew install fswatch
     Ubuntu: sudo apt-get install fswatch"
          ;;
      esac
    done
    
    if wait_for_user_action \
      "Missing required dependencies: ${missing_deps[*]}" \
      "$fix_instructions" \
      "check_dependencies"; then
      return 0
    else
      print_warning "Some dependencies are missing - script functionality may be limited"
      return 1
    fi
  fi
  
  print_success "All dependencies are available"
  return 0
}

# Validate environment configuration
function validate_environment() {
  echo "${STATUS_SCAN} Validating environment configuration..."
  
  # Check if .env file exists
  if [[ ! -f "$ENV_FILE" ]]; then
    print_error ".env file not found: $ENV_FILE"
    echo ""
    echo "${STATUS_TARGET} Let's set up your deployment environment!"
    interactive_setup
    return 0
  fi
  
  # Source and check for missing variables
  source "$ENV_FILE"
  
  local missing_vars=()
  for var in "${REQUIRED_VARS[@]}"; do
    if [[ -z "${!var}" ]]; then
      missing_vars+=("$var")
    fi
  done
  
  if [[ ${#missing_vars[@]} -gt 0 ]]; then
    print_error "Missing required environment variables: ${missing_vars[*]}"
    echo ""
    echo "${STATUS_TARGET} Let's complete your configuration!"
    interactive_setup
    return 0
  fi
  
  print_success "Environment configuration is valid"
  return 0
}

# Validate CloudFormation template
function validate_cloudformation_template() {
  while true; do
    echo "${STATUS_SCAN} Validating CloudFormation template..."
    
    # Re-source .env in case template path was updated
    source "$ENV_FILE"
    
    if [[ ! -f "$TEMPLATE_FILE" ]]; then
      local fix_instructions="   1. Check the path in TEMPLATE_FILE in your .env file:
      echo \"TEMPLATE_FILE=$TEMPLATE_FILE\"
   
   2. Verify the template file exists:
      ls -la $TEMPLATE_FILE
   
   3. Update TEMPLATE_FILE in .env with correct path
   
${STATUS_INFO} Common template locations found:"
      
      local template_candidates
      template_candidates=$(find . ../.. -name "*.yaml" -o -name "*.yml" -o -name "*.json" 2>/dev/null | grep -i template | head -5)
      if [[ -n "$template_candidates" ]]; then
        fix_instructions="$fix_instructions
$(echo "$template_candidates" | sed 's/^/   → /')"
      fi
      
      wait_for_user_action \
        "CloudFormation template not found: $TEMPLATE_FILE" \
        "$fix_instructions" \
        ""
      
      local action_result=$?
      if [[ $action_result -eq 0 ]]; then
        continue  # Try validation again
      else
        return 1  # User chose to skip/continue watching
      fi
    fi
    
    # Validate template syntax
    local validation_output
    if validation_output=$(aws cloudformation validate-template --template-body "file://$TEMPLATE_FILE" --region "$AWS_REGION" 2>&1); then
      print_success "CloudFormation template is valid"
      
      # Show template info
      local description=$(echo "$validation_output" | grep '"Description"' | cut -d'"' -f4 || echo "No description")
      echo "${STATUS_SUMMARY} Template: $description"
      
      return 0
    else
      echo ""
      print_error "CloudFormation template validation failed"
      echo ""
      echo "${STATUS_ANALYZE} Validation error details:"
      echo "$validation_output"
      echo ""
      
      # Parse specific error types for better guidance
      local specific_guidance=""
      if echo "$validation_output" | grep -q "unique names"; then
        specific_guidance="
${STATUS_ERROR} Duplicate Names Error:
   → You have duplicate resource or parameter names in your template
   → Search for 'FantasyDataBucket' in your template file
   → Each resource and parameter must have a unique name
   → Example fix: Rename one to 'FantasyDataBucket' and another to 'FantasyUserDataBucket'"
      elif echo "$validation_output" | grep -q "format error\|not well-formed"; then
        specific_guidance="
${STATUS_ERROR} YAML Syntax Error:
   → Check YAML indentation (use spaces, not tabs)
   → Ensure all strings with special characters are quoted
   → Validate YAML syntax online at yamllint.com"
      elif echo "$validation_output" | grep -q "Unresolved resource dependencies"; then
        specific_guidance="
${STATUS_ERROR} Resource Dependency Error:
   → Check that referenced resources exist
   → Verify !Ref and !GetAtt references point to valid resources
   → Ensure resource names match exactly (case-sensitive)"
      elif echo "$validation_output" | grep -q "Invalid template property"; then
        specific_guidance="
${STATUS_ERROR} Invalid Property Error:
   → Check CloudFormation documentation for correct property names
   → Verify resource types support the properties you're using
   → Check for typos in property names"
      fi
      
      local fix_instructions="   1. Open your template file in an editor:
      code $TEMPLATE_FILE
      # or
      nano $TEMPLATE_FILE
   
   2. Fix the validation error shown above
   
   3. Save the file and choose 'retry'
$specific_guidance

${STATUS_CONFIG} Common template debugging steps:
   → Use a YAML validator: yamllint.com
   → Check CloudFormation documentation for your resource types
   → Compare with working CloudFormation examples
   → Use AWS CloudFormation Designer for visual editing"
      
      wait_for_user_action \
        "Template validation failed" \
        "$fix_instructions" \
        ""
      
      local action_result=$?
      if [[ $action_result -eq 0 ]]; then
        continue  # User wants to retry - loop back to validation
      else
        return 1  # User chose to skip/continue watching
      fi
    fi
  done
}

# Validate S3 setup
function validate_s3_setup() {
  echo "${STATUS_SCAN} Validating S3 setup..."
  
  # Check if bucket exists and is accessible
  if ! aws s3 ls "s3://$BUCKET_NAME" --region "$AWS_REGION" >/dev/null 2>&1; then
    local fix_instructions="   1. Create the bucket:
      aws s3 mb s3://$BUCKET_NAME --region $AWS_REGION
   
   2. Or if bucket exists in different region:
      aws s3api get-bucket-location --bucket $BUCKET_NAME
      (then update AWS_REGION in .env)
   
   3. Or if permissions issue:
      aws sts get-caller-identity  # Check your AWS credentials
   
   4. Or if invalid bucket name:
      Update BUCKET_NAME in .env (must be globally unique)"
    
    if wait_for_user_action \
      "S3 bucket validation failed" \
      "$fix_instructions" \
      "validate_s3_setup"; then
      return 0
    else
      return 1
    fi
  fi
  
  # Test write permissions
  local test_key="deployment-test-$(date +%s).txt"
  if ! echo "test" | aws s3 cp - "s3://$BUCKET_NAME/$test_key" --region "$AWS_REGION" >/dev/null 2>&1; then
    local fix_instructions="   1. Check your AWS IAM permissions:
      Your user/role needs: s3:PutObject, s3:PutObjectAcl, s3:GetObject
   
   2. Check bucket policy allows your account to write
   
   3. Verify AWS credentials:
      aws sts get-caller-identity"
    
    if wait_for_user_action \
      "S3 write permission test failed" \
      "$fix_instructions" \
      "validate_s3_setup"; then
      return 0
    else
      return 1
    fi
  fi
  
  # Clean up test file
  aws s3 rm "s3://$BUCKET_NAME/$test_key" --region "$AWS_REGION" >/dev/null 2>&1
  
  print_success "S3 setup validated successfully"
  return 0
}

# Validate Lambda directory
function validate_lambda_directory() {
  local lambda_dir="${LAMBDA_SOURCE_DIR:-$DEFAULT_LAMBDA_DIR}"
  
  if [[ ! -d "$lambda_dir" ]]; then
    local fix_instructions="   1. Create the directory:
      mkdir -p $lambda_dir
   
   2. Add your Lambda code files (index.js, package.json, etc.)
   
   3. Or update LAMBDA_SOURCE_DIR in .env to point to existing code
   
${STATUS_INFO} Common locations where Lambda code might exist:"
    
    local js_files
    js_files=$(find . ../.. -name "*.js" -type f 2>/dev/null | grep -v node_modules | head -5)
    if [[ -n "$js_files" ]]; then
      fix_instructions="$fix_instructions
$(echo "$js_files" | sed 's|/[^/]*$||' | sort -u | sed 's/^/   → /')"
    fi
    
    if wait_for_user_action \
      "Lambda source directory not found: $lambda_dir" \
      "$fix_instructions" \
      "validate_lambda_directory"; then
      return 0
    else
      return 1
    fi
  fi
  
  # Check if directory has files
  if [[ -z $(find "$lambda_dir" -name "*.js" -o -name "*.json" | head -1) ]]; then
    local fix_instructions="   1. Add Lambda function files to: $lambda_dir
      Example: index.js, package.json
   
   2. Or run interactive setup to create sample files:
      Type 'setup' when prompted"
    
    if wait_for_user_action \
      "Lambda directory exists but contains no JavaScript files" \
      "$fix_instructions" \
      "validate_lambda_directory"; then
      return 0
    else
      return 1
    fi
  fi
  
  print_success "Lambda source directory is valid"
  return 0
}