#!/bin/bash

# Veza Development CLI
# Script principal pour gérer le développement du projet Veza

set -e

# Couleurs pour l'affichage
BLUE='\033[0;34m'
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Configuration
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
MANIFEST_FILE="$PROJECT_ROOT/.veza/feature-manifest.yaml"

# Fonctions utilitaires
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Vérifier que le manifeste existe
check_manifest() {
    if [[ ! -f "$MANIFEST_FILE" ]]; then
        log_error "Manifest file not found: $MANIFEST_FILE"
        exit 1
    fi
}

# Fonction pour valider la compatibilité
validate_compatibility() {
    log_info "Validating feature compatibility..."
    
    # Vérifier les dépendances
    if command -v yq &> /dev/null; then
        local features=$(yq eval '.features | keys | .[]' "$MANIFEST_FILE")
        for feature in $features; do
            log_info "Checking compatibility for feature: $feature"
            # Ici on pourrait ajouter des vérifications spécifiques
        done
        log_success "Compatibility validation completed"
    else
        log_warning "yq not installed, skipping compatibility validation"
    fi
}

# Fonction pour lancer les tests
run_tests() {
    local scope=${1:-"all"}
    
    log_info "Running tests for scope: $scope"
    
    case $scope in
        "core"|"all")
            log_info "Testing core backend..."
            cd "$PROJECT_ROOT/veza-backend-api"
            make test
            ;;
        "chat"|"all")
            log_info "Testing chat server..."
            cd "$PROJECT_ROOT/veza-chat-server"
            cargo test
            ;;
        "stream"|"all")
            log_info "Testing stream server..."
            cd "$PROJECT_ROOT/veza-stream-server"
            cargo test
            ;;
        *)
            log_error "Unknown scope: $scope"
            exit 1
            ;;
    esac
    
    log_success "Tests completed for scope: $scope"
}

# Fonction pour vérifier le format des commits
validate_commit_format() {
    local commit_msg="$1"
    local commit_regex='^\[(core|auth|chat|stream|market|docs|test)\]\[(feat|fix|refactor|test|docs|ci)\]'
    
    if ! echo "$commit_msg" | grep -qE "$commit_regex"; then
        log_error "Invalid commit format!"
        echo "Expected format: [SCOPE][TYPE] Description"
        echo "Examples:"
        echo "  [core][feat] Add user authentication"
        echo "  [chat][fix] Fix WebSocket connection"
        echo "  [docs][ci] Update API documentation"
        exit 1
    fi
    
    log_success "Commit format is valid"
}

# Fonction pour créer une nouvelle feature
create_feature() {
    local feature_name="$1"
    
    if [[ -z "$feature_name" ]]; then
        log_error "Feature name is required"
        echo "Usage: $0 new feature <feature-name>"
        exit 1
    fi
    
    log_info "Creating new feature: $feature_name"
    
    # Créer la structure de la feature
    local feature_dir="$PROJECT_ROOT/features/$feature_name"
    mkdir -p "$feature_dir"/{cmd,internal/{handlers,services,repositories,models},tests/{unit,integration,e2e},docs,migrations}
    
    # Générer le fichier de base de la feature
    cat > "$feature_dir/feature.go" << EOF
package $feature_name

import (
    "time"
    "github.com/okinrev/veza-web-app/internal/core/contracts"
)

type Feature struct {
    metadata contracts.FeatureMetadata
}

func New() contracts.FeatureContract {
    return &Feature{
        metadata: contracts.FeatureMetadata{
            Name:        "$feature_name",
            Version:     "0.1.0",
            Description: "TODO: Add description",
            Author:      "$(git config user.name)",
            CreatedAt:   time.Now(),
        },
    }
}

func (f *Feature) Validate(registry contracts.Registry) error {
    // TODO: Implement validation
    return nil
}

func (f *Feature) Initialize(registry contracts.Registry) error {
    // TODO: Implement initialization
    return nil
}
EOF

    # Créer le manifeste de la feature
    cat > "$feature_dir/manifest.yaml" << EOF
name: $feature_name
version: 0.1.0
description: "TODO: Add description"
dependencies:
  core: ">=1.0.0"
compatibility:
  min_version: "1.0.0"
  max_version: "2.0.0"
EOF

    log_success "Feature $feature_name created successfully!"
    log_info "Location: $feature_dir"
}

# Fonction pour déployer
deploy() {
    local environment="$1"
    
    if [[ -z "$environment" ]]; then
        log_error "Environment is required"
        echo "Usage: $0 deploy <environment>"
        echo "Environments: staging, production"
        exit 1
    fi
    
    log_info "Deploying to environment: $environment"
    
    case $environment in
        "staging")
            # Déploiement en staging
            log_info "Deploying to staging..."
            # Ici on ajouterait les commandes de déploiement
            ;;
        "production")
            # Déploiement en production
            log_info "Deploying to production..."
            # Ici on ajouterait les commandes de déploiement
            ;;
        *)
            log_error "Unknown environment: $environment"
            exit 1
            ;;
    esac
    
    log_success "Deployment to $environment completed"
}

# Fonction pour générer la documentation
generate_docs() {
    local doc_type="$1"
    
    log_info "Generating documentation: $doc_type"
    
    case $doc_type in
        "api")
            log_info "Generating API documentation..."
            # Générer la documentation API
            ;;
        "architecture")
            log_info "Generating architecture documentation..."
            # Générer la documentation d'architecture
            ;;
        "all")
            log_info "Generating all documentation..."
            # Générer toute la documentation
            ;;
        *)
            log_error "Unknown documentation type: $doc_type"
            exit 1
            ;;
    esac
    
    log_success "Documentation generation completed"
}

# Fonction pour synchroniser avec Cursor AI
sync_cursor() {
    log_info "Synchronizing with Cursor AI..."
    
    # Créer le dossier .cursor s'il n'existe pas
    mkdir -p "$PROJECT_ROOT/.cursor"
    
    # Générer le fichier de contexte
    cat > "$PROJECT_ROOT/.cursor/context.json" << EOF
{
    "project": "Veza",
    "architecture": "hexagonal",
    "features": {
        "core": {
            "status": "stable",
            "version": "1.0.0"
        },
        "chat-server": {
            "status": "stable",
            "version": "1.0.0"
        },
        "stream-server": {
            "status": "stable",
            "version": "1.0.0"
        }
    },
    "current_tasks": [],
    "validation_rules": [
        "version_compatibility",
        "interface_contracts",
        "event_consistency"
    ]
}
EOF

    log_success "Cursor AI context synchronized"
}

# Fonction d'aide
show_help() {
    echo "Veza Development CLI"
    echo ""
    echo "Usage: $0 <command> [options]"
    echo ""
    echo "Commands:"
    echo "  validate                    - Validate feature compatibility"
    echo "  test [scope]               - Run tests (core|chat|stream|all)"
    echo "  new feature <name>         - Create a new feature"
    echo "  deploy <environment>       - Deploy to environment (staging|production)"
    echo "  generate docs [type]       - Generate documentation (api|architecture|all)"
    echo "  sync-cursor                - Synchronize with Cursor AI"
    echo "  commit-validate <message>  - Validate commit message format"
    echo "  help                       - Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0 validate"
    echo "  $0 test core"
    echo "  $0 new feature auth"
    echo "  $0 deploy staging"
    echo "  $0 generate docs api"
    echo "  $0 commit-validate '[core][feat] Add user authentication'"
}

# Fonction principale
main() {
    check_manifest
    
    case "${1:-help}" in
        "validate")
            validate_compatibility
            ;;
        "test")
            run_tests "$2"
            ;;
        "new")
            if [[ "$2" == "feature" ]]; then
                create_feature "$3"
            else
                log_error "Unknown new command: $2"
                exit 1
            fi
            ;;
        "deploy")
            deploy "$2"
            ;;
        "generate")
            if [[ "$2" == "docs" ]]; then
                generate_docs "$3"
            else
                log_error "Unknown generate command: $2"
                exit 1
            fi
            ;;
        "sync-cursor")
            sync_cursor
            ;;
        "commit-validate")
            validate_commit_format "$2"
            ;;
        "help"|"--help"|"-h")
            show_help
            ;;
        *)
            log_error "Unknown command: $1"
            show_help
            exit 1
            ;;
    esac
}

# Exécuter la fonction principale
main "$@" 