#!/bin/bash
# Aptly Configuration Generator Script
# Generates configuration files for initialization and push scripts

set -e

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

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }

capitalize() {
  local s="$1"
  if [ -z "$s" ]; then
    printf ""
    return
  fi
  local first rest
  first=$(printf '%s' "$s" | cut -c1 | tr '[:lower:]' '[:upper:]')
  rest=$(printf '%s' "$s" | cut -c2-)
  printf '%s%s' "$first" "$rest"
}

# Default configuration variables (can be overridden by command line arguments)
APTLY_API_URL="https://apt.amianetworks.com.cn"
APTLY_USERNAME="developer"
APTLY_PASSWORD="@Amianetworks2025"
APTLY_VERIFY_SSL="false"
APTLY_TIMEOUT="30"
#APTLY_API_URL="https://apt-dev.amianetworks.com.cn"
#APTLY_USERNAME=""
#APTLY_PASSWORD=""
#APTLY_VERIFY_SSL="false"
#APTLY_TIMEOUT="30"
PRODUCTS=("dev" "stable")

# Output files
INIT_CONFIG_FILE="aptly_init_config.yaml"
PUSH_CONFIG_FILE="aptly_push_config.yaml"

# Function to show help
show_help() {
    cat << EOF
🚀 Aptly Configuration Generator

Usage: $0 [OPTIONS]

OPTIONS:
    -u, --url URL           Aptly API URL (default: $APTLY_API_URL)
    -n, --username USER     Aptly API username (default: $APTLY_USERNAME)
    -p, --password PASS     Aptly API password (default: $APTLY_PASSWORD)
    -s, --ssl BOOL          Verify SSL certificates (default: $APTLY_VERIFY_SSL)
    -t, --timeout SEC       API timeout in seconds (default: $APTLY_TIMEOUT)
    -P, --products LIST     Comma-separated product list (default: ${PRODUCTS[*]})
    -o, --output-dir DIR    Output directory for config files (default: current dir)
    -h, --help              Show this help message

EXAMPLES:
    # Use default settings
    $0

    # Custom API settings
    $0 --url "https://aptly.internal:2443" --username "admin" --password "ASN@2025!"

    # Custom products
    $0 --products "swan,asnc,custom-product"

    # Full custom configuration
    $0 -u "https://aptly.example.com:8080" -n "myuser" -p "mypass" -s true -P "product1,product2"

EOF
}

# Function to parse command line arguments
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -u|--url)
                APTLY_API_URL="$2"
                shift 2
                ;;
            -n|--username)
                APTLY_USERNAME="$2"
                shift 2
                ;;
            -p|--password)
                APTLY_PASSWORD="$2"
                shift 2
                ;;
            -s|--ssl)
                APTLY_VERIFY_SSL="$2"
                shift 2
                ;;
            -t|--timeout)
                APTLY_TIMEOUT="$2"
                shift 2
                ;;
            -P|--products)
                IFS=',' read -ra PRODUCTS <<< "$2"
                shift 2
                ;;
            -o|--output-dir)
                OUTPUT_DIR="$2"
                INIT_CONFIG_FILE="$OUTPUT_DIR/$INIT_CONFIG_FILE"
                PUSH_CONFIG_FILE="$OUTPUT_DIR/$PUSH_CONFIG_FILE"
                mkdir -p "$OUTPUT_DIR"
                shift 2
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            *)
                log_error "Unknown option: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

# Function to generate initialization config
generate_init_config() {
    log_info "Generating initialization script configuration..."
    
    cat > "$INIT_CONFIG_FILE" << EOF
# Aptly Repository Initialization Configuration
# Generated automatically based on snapshot rules

# Aptly API Configuration
api:
  base_url: "$APTLY_API_URL"
  username: "$APTLY_USERNAME"
  password: "$APTLY_PASSWORD"
  verify_ssl: $APTLY_VERIFY_SSL

# Repository Definitions
repositories:
EOF

    # Generate repository definitions for each repo name
    for product in "${PRODUCTS[@]}"; do
        cap=$(capitalize "$product")
        cat >> "$INIT_CONFIG_FILE" << EOF
  - name: "${product}"
    distribution: "${product}"
    component: "main"
    prefix: "."
    description: "${cap} repository"

EOF
    done

    # Add remaining configuration
    cat >> "$INIT_CONFIG_FILE" << EOF
# Snapshot Configuration
snapshot:
  name_template: "Snapshot-{repo_name}_{timestamp}"
  description_template: "Initial empty snapshot for {repo_name}. Created by initialization script on {timestamp}."
  timestamp_format: "%Y%m%d_%H%M%S"

# Logging Configuration
logging:
  level: "INFO"
  log_file: "aptly_init.log"
  console_output: true

# Push Script Logging Configuration
push_logging:
  level: "INFO"
  log_file: "aptly_push.log"
  console_output: true

# Package Parsing Rules
package_rules:
  # Version format: Y.M.B (Year.Month.Build)
  # Stable: B < 100, Dev: B >= 100
  version_pattern: '^(\\d+)\\.(\\d+)\\.(\\d+)$'
  dev_threshold: 100

  # Product name mappings from package names
  product_mappings:
EOF

    # Generate product mappings
    for product in "${PRODUCTS[@]}"; do
        cat >> "$INIT_CONFIG_FILE" << EOF
    "${product}-manager": "${product}"
    "${product}-servicenode": "${product}"
EOF
    done

    log_success "Generated initialization config: $INIT_CONFIG_FILE"
}

# Function to generate push config
generate_push_config() {
    log_info "Generating push script configuration..."
    
    cat > "$PUSH_CONFIG_FILE" << EOF
# Aptly Push Script Configuration
# Generated automatically based on snapshot rules

# ==========================================
# Aptly API Server Configuration
# ==========================================
aptly:
  api_url: "$APTLY_API_URL"
  timeout: $APTLY_TIMEOUT
  verify_ssl: $APTLY_VERIFY_SSL
  username: "$APTLY_USERNAME"
  password: "$APTLY_PASSWORD"

# ==========================================
# Product Version Rules Configuration
# ==========================================
version_rules:
  # Version format: Y.M.B (Year.Month.Build)
  # Stable: B < 100, Development: B >= 100
  stable_threshold: 100
  version_pattern: '^(\\d+)\\.(\\d+)\\.(\\d+)$'

# ==========================================
# DEB Package Naming Rules
# ==========================================
package_naming:
  # Package format: product_version_architecture.deb
  # Examples: asnc_25.7.13_amd64.deb, swan_24.12.5_amd64.deb
  pattern: '^([a-zA-Z0-9-]+)_([0-9.]+)_([a-zA-Z0-9]+)\.deb$'
  groups:
    product: 1
    version: 2
    architecture: 3

# ==========================================
# Product Repository Mapping Rules
# ==========================================
repositories:
EOF

    # Generate repository configurations
    for product in "${PRODUCTS[@]}"; do
        cap=$(capitalize "$product")
        cat >> "$PUSH_CONFIG_FILE" << EOF
  # ${cap} Repository
  ${product}:
    name: "${product}"
    distribution: "${product}"
    component: "main"
    architectures: ["amd64"]
    temp_dir: "files/${product}"
    prefix: "."
    
EOF
    done

    # Add product mapping section
    cat >> "$PUSH_CONFIG_FILE" << EOF
# ==========================================
# Product Mapping Rules
# ==========================================
product_mapping:
EOF

    for product in "${PRODUCTS[@]}"; do
        cap=$(capitalize "$product")
        cat >> "$PUSH_CONFIG_FILE" << EOF
  # ${cap} repository mapping
  ${product}:
    stable_repo: "${product}"
    dev_repo: "${product}"
    components: ["*"]  # All components
    
EOF
    done

    # Add remaining configuration sections
    cat >> "$PUSH_CONFIG_FILE" << EOF
# ==========================================
# Push Workflow Configuration
# ==========================================
push_workflow:
  # Push steps
  steps:
    - "parse_package_name"      # 1. Parse deb package name
    - "determine_repository"    # 2. Determine target repository based on product and version
    - "upload_to_temp"         # 3. Upload deb package to temp directory
    - "add_to_repository"      # 4. Add packages from temp directory to APT repository
    - "create_snapshot"        # 5. Create snapshot from APT repository
    - "update_publish"         # 6. Update publish endpoint
    
  # Auto cleanup temp files
  auto_cleanup: true
  
  # Verify after push
  verify_after_push: true
  
  # Rollback on failure
  rollback_on_failure: true

# ==========================================
# Snapshot Configuration
# ==========================================
snapshot_config:
  # Snapshot naming rule
  name_pattern: "Snapshot-{repo_name}_{timestamp}"
  
  # Snapshot description
  description: "Created by aptly_push.py script"
  
  # Timestamp format
  timestamp_format: "%Y%m%d_%H%M%S"
  
  # Keep history snapshots
  keep_history: true
  
  # Maximum snapshots to keep
  max_snapshots: 10

# ==========================================
# Temp Directory Configuration
# ==========================================
temp_directories:
  # Temp files root directory
  base_path: "files"
  
  # Auto create temp directories
  auto_create: true
  
  # Temp directory permissions
  permissions: "755"
  
  # Cleanup after upload
  cleanup_after_upload: false

# ==========================================
# Logging Configuration
# ==========================================
push_logging:
  level: "INFO"
  log_file: "logs/aptly_push.log"
  console_output: true
  format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
  
  # Log rotation
  max_size: "10MB"
  backup_count: 5

# ==========================================
# Retry and Error Handling Configuration
# ==========================================
retry:
  # Maximum retry attempts
  max_attempts: 3
  
  # Retry interval (seconds)
  delay: 2
  
  # Retry interval increment factor
  backoff_factor: 2
  
  # Error types that need retry
  retry_on_errors: ["ConnectionError", "Timeout", "HTTPError"]

# ==========================================
# Validation Configuration
# ==========================================
validation:
  # Verify package file before push
  verify_package_integrity: true
  
  # Verify package name format
  verify_package_naming: true
  
  # Verify target repository exists
  verify_target_repository: true
  
  # Verify package in repository after push
  verify_package_in_repo: true

# ==========================================
# Notification Configuration (Optional)
# ==========================================
notifications:
  # Enable notifications
  enabled: false
  
  # Success notifications
  on_success: true
  
  # Failure notifications
  on_failure: true
  
  # Notification methods
  methods:
    - "log"  # Log to file
    # - "email"  # Email notification
    # - "webhook"  # Webhook notification
EOF

    log_success "Generated push config: $PUSH_CONFIG_FILE"
}

# Function to show usage information
show_usage() {
    log_info "Generated configuration files for Aptly scripts"
    echo
    echo "📝 Next Steps:"
    echo "   1. Initialize repositories: python3 scripts/aptly_init.py -c $INIT_CONFIG_FILE"
    echo "   2. Push packages: python3 aptly_push.py -c $PUSH_CONFIG_FILE /path/to/packages/"
    echo
    echo "📊 Generated repositories based on your configuration:"
    for product in "${PRODUCTS[@]}"; do
        echo "   - ${product}"
    done
    echo
    echo "🎯 Example package push commands:"
    echo "   # Force push to specific repository"
    echo "   python3 aptly_push.py -c $PUSH_CONFIG_FILE --force-repo asnc-stable package.deb"
    echo
    echo "   # Auto-detect repository based on version"
    echo "   python3 aptly_push.py -c $PUSH_CONFIG_FILE /path/to/packages/"
    echo
    echo "🔧 Configuration files generated:"
    echo "   - $INIT_CONFIG_FILE (for repository initialization)"
    echo "   - $PUSH_CONFIG_FILE (for package pushing)"
    echo
    echo "💡 Tip: Use --help with any script to see all available options"
}

# Function to validate configuration
validate_config() {
    log_info "Validating configuration..."

    # Validate URL format
    if [[ ! "$APTLY_API_URL" =~ ^https?:// ]]; then
        log_error "Invalid API URL format: $APTLY_API_URL"
        exit 1
    fi

    # Validate timeout is numeric
    if ! [[ "$APTLY_TIMEOUT" =~ ^[0-9]+$ ]]; then
        log_error "Timeout must be a number: $APTLY_TIMEOUT"
        exit 1
    fi

    # Validate SSL setting
    if [[ "$APTLY_VERIFY_SSL" != "true" && "$APTLY_VERIFY_SSL" != "false" ]]; then
        log_error "SSL verification must be 'true' or 'false': $APTLY_VERIFY_SSL"
        exit 1
    fi

    # Validate products array is not empty
    if [[ ${#PRODUCTS[@]} -eq 0 ]]; then
        log_error "Products list cannot be empty"
        exit 1
    fi

    log_success "Configuration validation passed"
}

# Main function
main() {
    # Parse command line arguments first
    parse_arguments "$@"

    echo "🚀 Aptly Configuration Generator"
    echo "================================"
    echo

    # Validate configuration
    validate_config

    log_info "Products: ${PRODUCTS[*]}"
    log_info "API URL: $APTLY_API_URL"
    log_info "Username: $APTLY_USERNAME"
    log_info "SSL Verification: $APTLY_VERIFY_SSL"
    log_info "Timeout: ${APTLY_TIMEOUT}s"
    echo

    # Generate configurations
    generate_init_config
    generate_push_config

    echo
    log_success "Configuration generation completed!"
    echo

    show_usage
}

# Run main function
main "$@"