#!/usr/bin/env bash

# Fluent Validation Script using native工具和Rust
# Validates Fluent (.ftl) files for syntax errors and structural issues

set -euo pipefail

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

# Configuration
CONTENT_DIR="content"
VERBOSE=${VERBOSE:-false}
STRICT=${STRICT:-false}
REPORT_FILE=""

# Error tracking
ERRORS=0
WARNINGS=0
TOTAL_FILES=0

print_usage() {
    cat << EOF
Usage: $0 [OPTIONS] [DIRECTORY]

Validate Fluent (.ftl) localization files for syntax and structure errors.

OPTIONS:
    -f, --file FILE        Validate specific FTL file
    -v, --verbose         Enable verbose output
    -s, --strict          Treat warnings as errors
    -r, --report FILE     Generate JSON report file
    -h, --help           Show this help message

EXAMPLES:
    $0                    # Validate all FTL files in content/
    $0 content/en         # Validate English FTL files
    $0 -f content/en/auth.ftl  # Validate specific file
    $0 -v -r report.json   # Verbose with JSON report

ENVIRONMENT VARIABLES:
    VERBOSE=true          Enable verbose output
    STRICT=true           Treat warnings as errors
EOF
}

log() {
    echo -e "${CYAN}[VALIDATE]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1" >&2
    ((ERRORS++))
}

log_warning() {
    echo -e "${YELLOW}[WARN]${NC} $1"
    ((WARNINGS++))
}

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

# Check if required tools are available
check_dependencies() {
    if ! command -v cargo &> /dev/null; then
        log_error "Cargo not found. Please install Rust toolchain."
        exit 1
    fi
}

# Install fluent-syntax tool if needed
install_fluent_tool() {
    if ! command -v fluent-syntax &> /dev/null; then
        log "Creating simple fluent parser..."
        # Create a simple validate tool if fluent-cli not available
        cat > /tmp/validate_ftl.rs << 'EOF'
use std::fs;
use std::env;
use std::process;

fn validate_ftl_file(file_path: &str) -> Result<(), String> {
    let content = fs::read_to_string(file_path)
        .map_err(|e| format!("Failed to read file: {}", e))?;

    // Basic FTL validation: check for unbalanced braces
    let open_braces = content.chars().filter(|&c| c == '{').count();
    let close_braces = content.chars().filter(|&c| c == '}').count();

    if open_braces != close_braces {
        return Err(format!("Unbalanced braces: {} open, {} close", open_braces, close_braces));
    }

    // Basic syntax validation
    for (line_num, line) in content.lines().enumerate() {
        let line = line.trim();
        if line.is_empty() || line.starts_with('#') {
            continue;
        }

        // Check for message format
        if line.contains('=') && !line.starts_with('[') {
            let parts: Vec<&str> = line.splitn(2, '=').collect();
            if parts.len() != 2 {
                return Err(format!("Line {}: Invalid message format", line_num + 1));
            }

            let key = parts[0].trim();
            if key.is_empty() {
                return Err(format!("Line {}: Empty message key", line_num + 1));
            }

            // Check for valid key characters
            if !key.chars().all(|c| c.is_alphanumeric() || c == '-' || c == '_') {
                return Err(format!("Line {}: Invalid key characters: {}", line_num + 1, key));
            }
        }
    }

    Ok(())
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        eprintln!("Usage: validate_ftl <file.ftl>");
        process::exit(1);
    }

    match validate_ftl_file(&args[1]) {
        Ok(()) => {
            println!("✓ {}: Valid", args[1]);
            process::exit(0);
        }
        Err(e) => {
            eprintln!("✗ {}: {}", args[1], e);
            process::exit(1);
        }
    }
}
EOF
        rustc /tmp/validate_ftl.rs -o /tmp/validate_ftl
        export PATH="/tmp:$PATH"
    fi
}

# Validate a single FTL file
validate_ftl_file() {
    local file="$1"
    local errors=0

    if [[ ! -f "$file" ]]; then
        log_error "File not found: $file"
        return 1
    fi

    ((TOTAL_FILES++))

    log "Validating: $file"

    # Check UTF-8 encoding
    if ! iconv -f UTF-8 -t UTF-8 "$file" >/dev/null 2>&1; then
        log_error "File is not valid UTF-8: $file"
        ((errors++))
    fi

    # Check for BOM (Byte Order Mark)
    if head -c 3 "$file" | grep -q '\xEF\xBB\xBF'; then
        log_warning "File contains UTF-8 BOM: $file"
    fi

    # Check for mixed line endings
    if file "$file" | grep -q "CRLF"; then
        log_warning "Mixed line endings (CRLF detected): $file"
    fi

    # Use basic validation tool
    if command -v fluent-syntax &> /dev/null; then
        if fluent-syntax validate "$file" > /dev/null 2>&1; then
            log_success "$file: Valid syntax"
        else
            log_error "$file: Syntax error"
            if [[ "$VERBOSE" == "true" ]]; then
                fluent-syntax validate "$file"
            fi
            ((errors++))
        fi
    else
        # Use simple validation
        if /tmp/validate_ftl "$file" 2>/dev/null; then
            log_success "$file: Valid"
        else
            log_error "$file: Validation failed"
            ((errors++))
        fi
    fi

    # Custom checks for common issues
    local content
    content=$(cat "$file")

    # Check for unbalanced braces
    local open_braces
    local close_braces
    open_braces=$(grep -o '{' <<< "$content" | wc -l)
    close_braces=$(grep -o '}' <<< "$content" | wc -l)

    if [[ $open_braces -ne $close_braces ]]; then
        log_error "$file: Unbalanced braces ($open_braces open, $close_braces close)"
        ((errors++))
    fi

    # Check for empty messages
    while IFS= read -r line; do
        if [[ "$line" =~ ^[a-zA-Z0-9_-]+[[:space:]]*=[[:space:]]*$ ]]; then
            log_warning "$file: Empty message value: $line"
        fi
    done <<< "$content"

    # Check for duplicate keys
    local keys
    keys=$(grep -E '^[a-zA-Z0-9\-_]+[[:space:]]*=' "$file" | cut -d'=' -f1 | sed 's/[[:space:]]*$//')
    local duplicate_keys
    duplicate_keys=$(echo "$keys" | sort | uniq -d)

    if [[ -n "$duplicate_keys" ]]; then
        log_error "$file: Duplicate keys found: $duplicate_keys"
        ((errors++))
    fi

    return $errors
}

# Validate all FTL files in directory
validate_directory() {
    local dir="$1"
    local files_found=0

    if [[ ! -d "$dir" ]]; then
        log_error "Directory not found: $dir"
        return 1
    fi

    log "Searching for FTL files in: $dir"

    # Find all .ftl files recursively
    while IFS= read -r -d '' file; do
        validate_ftl_file "$file"
        ((files_found++))
    done < <(find "$dir" -name "*.ftl" -type f -print0)

    if [[ $files_found -eq 0 ]]; then
        log_warning "No FTL files found in: $dir"
    fi
}

# Generate JSON report
generate_report() {
    local output_file="$1"

    cat > "$output_file" << EOF
{
  "validation": {
    "total_files": $TOTAL_FILES,
    "errors": $ERRORS,
    "warnings": $WARNINGS,
    "success": $(($TOTAL_FILES - $ERRORS)),
    "timestamp": "$(date -Iseconds)",
    "content_dir": "$CONTENT_DIR"
  }
}
EOF

    log "Report saved to: $output_file"
}

# Main validation function
main() {
    local target_dir="$CONTENT_DIR"
    local target_file=""

    # Parse command line arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            -f|--file)
                target_file="$2"
                shift 2
                ;;
            -v|--verbose)
                VERBOSE=true
                shift
                ;;
            -s|--strict)
                STRICT=true
                shift
                ;;
            -r|--report)
                REPORT_FILE="$2"
                shift 2
                ;;
            -h|--help)
                print_usage
                exit 0
                ;;
            *)
                target_dir="$1"
                shift
                ;;
        esac
    done

    # Override with environment variables
    [[ -n "${VERBOSE:-}" ]] && VERBOSE=true
    [[ -n "${STRICT:-}" ]] && STRICT=true

    log "Starting Fluent validation"
    check_dependencies
    install_fluent_tool

    if [[ -n "$target_file" ]]; then
        validate_ftl_file "$target_file"
    else
        validate_directory "$target_dir"
    fi

    # Generate report if requested
    if [[ -n "$REPORT_FILE" ]]; then
        generate_report "$REPORT_FILE"
    fi

    # Final summary
    echo
    echo "=== VALIDATION SUMMARY ==="
    echo "Total files processed: $TOTAL_FILES"
    echo -e "Errors: ${RED}$ERRORS${NC}"
    echo -e "Warnings: ${YELLOW}$WARNINGS${NC}"

    if [[ $ERRORS -gt 0 ]]; then
        echo -e "${RED}✗ Validation failed with errors${NC}"
        exit 1
    elif [[ $WARNINGS -gt 0 ]] && [[ "$STRICT" == "true" ]]; then
        echo -e "${YELLOW}⚠ Validation failed with warnings (strict mode)${NC}"
        exit 1
    elif [[ $WARNINGS -gt 0 ]]; then
        echo -e "${YELLOW}⚠ Validation passed with warnings${NC}"
        exit 0
    else
        echo -e "${GREEN}✓ Validation passed successfully${NC}"
        exit 0
    fi
}

# Run main function if script is executed directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi
