#!/bin/bash
set -euo pipefail

# CODEX-BUILD-001: CI/CD Integration for Feature-Aware Builds
# Comprehensive CI/CD script supporting multiple build configurations

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

# CI Configuration
CI_MODE="${CI_MODE:-full}"  # basic, features, full
RUST_VERSION="${RUST_VERSION:-stable}"
PARALLEL_JOBS="${PARALLEL_JOBS:-4}"
ARTIFACT_RETENTION="${ARTIFACT_RETENTION:-7}"  # days

print_ci_banner() {
    echo -e "${BLUE}==============================${NC}"
    echo -e "${BLUE}  Codex CI/CD Build Pipeline  ${NC}"
    echo -e "${BLUE}==============================${NC}"
    echo "CI Mode: $CI_MODE"
    echo "Rust Version: $RUST_VERSION"
    echo "Parallel Jobs: $PARALLEL_JOBS"
    echo ""
}

setup_rust_environment() {
    echo -e "${BLUE}Setting up Rust environment...${NC}"
    
    # Install Rust if not present (for CI environments)
    if ! command -v rustc &> /dev/null; then
        echo "Installing Rust toolchain..."
        curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
        source ~/.cargo/env
    fi
    
    # Ensure correct Rust version
    rustup default "$RUST_VERSION"
    rustup component add clippy rustfmt
    
    echo "Rust version: $(rustc --version)"
    echo "Cargo version: $(cargo --version)"
    echo ""
}

lint_and_format_check() {
    echo -e "${BLUE}Running code quality checks...${NC}"
    
    # Format check
    echo "Checking code formatting..."
    if ! cargo fmt -- --check; then
        echo -e "${RED}Code formatting check failed. Run 'cargo fmt' to fix.${NC}"
        exit 1
    fi
    
    # Clippy check (both configurations)
    echo "Running clippy (basic configuration)..."
    if ! cargo clippy -- -D warnings; then
        echo -e "${RED}Clippy check failed for basic configuration${NC}"
        exit 1
    fi
    
    echo "Running clippy (with features)..."
    if ! cargo clippy --features  -- -D warnings; then
        echo -e "${RED}Clippy check failed for feature configuration${NC}"
        exit 1
    fi
    
    echo -e "${GREEN}Code quality checks passed${NC}"
    echo ""
}

build_matrix() {
    echo -e "${BLUE}Building configuration matrix...${NC}"
    
    local configurations=()
    
    case "$CI_MODE" in
        "basic")
            configurations=("basic")
            ;;
        "features") 
            configurations=("")
            ;;
        "full")
            configurations=("basic" "")
            ;;
        *)
            echo -e "${RED}Invalid CI_MODE: $CI_MODE${NC}"
            exit 1
            ;;
    esac
    
    for config in "${configurations[@]}"; do
        build_configuration "$config"
    done
    
    echo -e "${GREEN}All configurations built successfully${NC}"
    echo ""
}

build_configuration() {
    local config="$1"
    echo -e "${YELLOW}Building configuration: $config${NC}"
    
    if [[ "$config" == "basic" ]]; then
        # Basic build without features
        cargo build --release
        check_build_artifact "Basic" "target/release/codex-memory"
    else
        # Feature-enabled build
        cargo build --release --features "$config"
        check_build_artifact "Feature ($config)" "target/release/codex-memory"
        
        # Verify feature dependencies are included
        verify_feature_inclusion "$config"
    fi
}

check_build_artifact() {
    local description="$1"
    local artifact_path="$2"
    
    if [[ ! -f "$artifact_path" ]]; then
        echo -e "${RED}Error: $description build artifact not found at $artifact_path${NC}"
        exit 1
    fi
    
    local size=$(du -h "$artifact_path" | cut -f1)
    echo "  $description artifact: $size"
}

verify_feature_inclusion() {
    local features="$1"
    echo "  Verifying feature dependencies for: $features"
    
    # Check that feature dependencies are in the build
    if cargo tree --features "$features" | grep -E "(ollama-rs|tokenizers|candle-core)" > /dev/null; then
        echo "  ✅ Feature dependencies confirmed"
    else
        echo -e "${RED}  ❌ Feature dependencies not found${NC}"
        exit 1
    fi
}

run_test_matrix() {
    echo -e "${BLUE}Running test matrix...${NC}"
    
    # Run tests without features
    echo "Testing basic configuration..."
    if ! cargo test --lib; then
        echo -e "${RED}Basic configuration tests failed${NC}"
        exit 1
    fi
    
    # Run tests with features (if applicable)
    if [[ "$CI_MODE" == "features" ]] || [[ "$CI_MODE" == "full" ]]; then
        echo "Testing feature configuration..."
        if ! cargo test --lib --features ; then
            echo -e "${RED}Feature configuration tests failed${NC}"
            exit 1
        fi
    fi
    
    # Run build system tests
    echo "Testing build system..."
    if ! cargo test --test build_system_test; then
        echo -e "${RED}Build system tests failed${NC}"
        exit 1
    fi
    
    echo -e "${GREEN}All test configurations passed${NC}"
    echo ""
}

security_audit() {
    echo -e "${BLUE}Running security audit...${NC}"
    
    # Install cargo-audit if not present
    if ! command -v cargo-audit &> /dev/null; then
        echo "Installing cargo-audit..."
        cargo install cargo-audit
    fi
    
    # Run security audit
    if ! cargo audit; then
        echo -e "${RED}Security audit found vulnerabilities${NC}"
        exit 1
    fi
    
    echo -e "${GREEN}Security audit passed${NC}"
    echo ""
}

package_artifacts() {
    echo -e "${BLUE}Packaging CI artifacts...${NC}"
    
    local artifact_dir="ci-artifacts-$(date +%Y%m%d-%H%M%S)"
    mkdir -p "$artifact_dir"
    
    # Copy binaries if they exist
    if [[ -f "target/release/codex-memory" ]]; then
        cp "target/release/codex-memory" "$artifact_dir/"
        echo "  ✅ Binary packaged"
    fi
    
    # Create metadata file
    cat > "$artifact_dir/build-info.json" << EOF
{
    "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "ci_mode": "$CI_MODE",
    "rust_version": "$(rustc --version)",
    "features_enabled": $(if [[ "$CI_MODE" == "basic" ]]; then echo "false"; else echo "true"; fi),
    "binary_size_bytes": $(if [[ -f "target/release/codex-memory" ]]; then stat -c%s "target/release/codex-memory" 2>/dev/null || stat -f%z "target/release/codex-memory"; else echo "null"; fi),
    "test_results": "passed"
}
EOF
    
    echo "  ✅ Metadata packaged"
    echo "  📦 Artifacts in: $artifact_dir/"
    echo ""
}

print_summary() {
    echo -e "${GREEN}==============================${NC}"
    echo -e "${GREEN}  CI/CD Build Summary          ${NC}"
    echo -e "${GREEN}==============================${NC}"
    echo "Mode: $CI_MODE"
    echo "Duration: ${SECONDS}s"
    echo "Status: SUCCESS"
    
    if [[ -f "target/release/codex-memory" ]]; then
        local size=$(du -h "target/release/codex-memory" | cut -f1)
        echo "Final artifact: codex-memory ($size)"
    fi
    echo ""
}

main() {
    local start_time=$SECONDS
    
    print_ci_banner
    setup_rust_environment
    lint_and_format_check
    build_matrix
    run_test_matrix
    security_audit
    package_artifacts
    print_summary
    
    echo -e "${GREEN}CI/CD pipeline completed successfully in ${SECONDS}s${NC}"
}

# Help function
show_help() {
    echo "Codex CI/CD Build Pipeline"
    echo ""
    echo "Usage: $0 [options]"
    echo ""
    echo "Environment Variables:"
    echo "  CI_MODE=basic|features|full  CI build mode (default: full)"
    echo "  RUST_VERSION=stable|beta     Rust version (default: stable)"
    echo "  PARALLEL_JOBS=N              Parallel job count (default: 4)"
    echo ""
    echo "CI Modes:"
    echo "  basic     - Build only without features"
    echo "  features  - Build only with  features" 
    echo "  full      - Build both basic and feature configurations"
    echo ""
    echo "Examples:"
    echo "  # Full CI pipeline (recommended)"
    echo "  ./scripts/ci-build.sh"
    echo ""
    echo "  # Feature-only CI (faster)"
    echo "  CI_MODE=features ./scripts/ci-build.sh"
    echo ""
    echo "  # Basic-only CI (minimal)"
    echo "  CI_MODE=basic ./scripts/ci-build.sh"
}

# Handle help flag
if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
    show_help
    exit 0
fi

# Run main CI pipeline
main "$@"