#!/bin/bash
# MCP-ZERO Burn Folder Generator
# Enterprise-grade deployment tool for creating named, portable MCP-ZERO environments
# Used to create advanced agent training and execution environments OUTSIDE the main project
# Enhanced with offline-first resilience and CI compatibility

# Don't use set -e to ensure offline-first resilience with fallbacks

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

# Base paths with fallbacks for CI environments
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd || echo "/tmp/mcp_zero")"
TEMPLATES_DIR="${SOURCE_DIR}/templates"

# Print colored message function
print_message() {
  local color=$1
  local message=$2
  echo -e "${color}${message}${NC}"
}

# Create burn folder lock file
echo "MCP-ZERO Burn Folder Generator" > "${BURN_FOLDER}/burn.lock"
echo "Created at $(date)" >> "${BURN_FOLDER}/burn.lock"
echo "Options:" >> "${BURN_FOLDER}/burn.lock"
echo "  Offline mode: ${OFFLINE_MODE}" >> "${BURN_FOLDER}/burn.lock"
echo "  Docker config: ${DOCKER_CONFIG}" >> "${BURN_FOLDER}/burn.lock"
echo "  Agent config: ${AGENT_CONFIG}" >> "${BURN_FOLDER}/burn.lock"
echo "  LLM config: ${LLM_CONFIG}" >> "${BURN_FOLDER}/burn.lock"
echo "  DB only: ${DB_ONLY}" >> "${BURN_FOLDER}/burn.lock"
echo "  CI mode: ${CI_MODE}" >> "${BURN_FOLDER}/burn.lock"
echo "  Terraform config: ${TERRAFORM_CONFIG}" >> "${BURN_FOLDER}/burn.lock"
echo "  Burn contracts: ${BURN_CONTRACTS}" >> "${BURN_FOLDER}/burn.lock"
echo "  Port: ${PORT}" >> "${BURN_FOLDER}/burn.lock"

# Check if running in CI environment
CI_MODE=${CI:-false}
if [ "$CI" == "true" ] || [ "$GITHUB_ACTIONS" == "true" ]; then
  CI_MODE=true
  echo "CI environment detected, enabling CI mode automatically"
fi

# Source template scripts with fallbacks
source_template() {
  local template_name="$1"
  
  # Check if template script exists
  if [ -f "${SCRIPT_DIR}/templates/${template_name}.sh" ]; then
    source "${SCRIPT_DIR}/templates/${template_name}.sh"
    echo "Sourced ${template_name}.sh successfully" >> "${BURN_FOLDER}/burn.lock"
    return 0
  else
    echo -e "${YELLOW}Warning: ${template_name}.sh not found, creating minimal fallback"
    echo "Template ${template_name}.sh missing, using fallback" >> "${BURN_FOLDER}/burn.lock"
    
    # Create minimal fallback function
    eval "${template_name}_fallback() { 
      echo 'Fallback implementation for ${template_name}' >> \"${BURN_FOLDER}/burn.lock\"; 
      mkdir -p \"${BURN_FOLDER}/fallback\"; 
      echo '# Fallback for ${template_name}' > \"${BURN_FOLDER}/fallback/${template_name}_fallback.sh\"; 
      chmod +x \"${BURN_FOLDER}/fallback/${template_name}_fallback.sh\"; 
      print_message \"${YELLOW}\" \"Created fallback for ${template_name}\"; 
    }"
    
    # Define the function to call
    eval "${template_name}() { ${template_name}_fallback \"\$@\"; }"
    
    return 1
  fi
}

# Source dependency checker first
source_with_fallback "${TEMPLATES_DIR}/dependency_checker.sh"

# Parse command line arguments
parse_arguments() {
  OFFLINE_MODE=false
  DOCKER_CONFIG=false
  AGENT_CONFIG=false
  LLM_CONFIG=false
  DB_ONLY=false
  CI_MODE=false
  TERRAFORM_CONFIG=false
  BURN_CONTRACTS=false
  PORT=8080

  # Detect CI environment
  if [ "$CI" == "true" ] || [ "$GITHUB_ACTIONS" == "true" ]; then
    CI_MODE=true
    echo "CI environment detected, enabling CI mode automatically"
  fi

  # Check for offline-first environment variable
  if [ "$OFFLINE_FIRST" == "1" ]; then
    OFFLINE_MODE=true
    echo "OFFLINE_FIRST environment variable detected, enabling offline mode"
  fi

  while [[ $# -gt 0 ]]; do
    case $1 in
      --offline)
        OFFLINE_MODE=true
        shift
        ;;
      --docker)
        DOCKER_CONFIG=true
        shift
        ;;
      --agents)
        AGENT_CONFIG=true
        shift
        ;;
      --llm)
        LLM_CONFIG=true
        shift
        ;;
      --db-only)
        DB_ONLY=true
        shift
        ;;
      --ci)
        CI_MODE=true
        shift
        ;;
      --terraform)
        TERRAFORM_CONFIG=true
        shift
        ;;
      --burn-contracts)
        BURN_CONTRACTS=true
        shift
        ;;
      --port)
        PORT=$2
        shift 2
        ;;
      --help)
        usage
        ;;
      -*)
        echo "Unknown option: $1"
        usage
        ;;
      *)
        BURN_FOLDER=$1
        shift
        ;;
    esac
  done
}

# Generate configuration files
generate_config_files() {
  print_message "${BLUE}" "Generating configuration files..."
  
  # Generate configuration files
  source_template "config_generator"
  create_config_files "${BURN_FOLDER}" "${PORT}" "${OFFLINE_MODE}"
}

# Set up database
setup_database() {
  print_message "${BLUE}" "Setting up database..."
  source_template "database_setup"
  setup_database "${BURN_FOLDER}"
}

# Include Docker configurations if requested
generate_docker_files() {
  if [ "${DOCKER_CONFIG}" = true ]; then
    print_message "${BLUE}" "Including Docker configurations..."
    source_template "docker_generator"
    generate_docker_files "${BURN_FOLDER}" "${PORT}" "${OFFLINE_MODE}"
  fi
}

# Include agent configurations if requested
setup_agents() {
  if [ "${AGENT_CONFIG}" = true ]; then
    print_message "${BLUE}" "Including agent configurations..."
    source_template "agent_setup"
    setup_agents "${BURN_FOLDER}"
    if [ ${INCLUDE_DOCKER} -eq 0 ]; then
      print_message "${YELLOW}" "Enabling Docker for LLM support"
      INCLUDE_DOCKER=1
      generate_all_docker "${TARGET_DIR}/docker" "${API_PORT}" "${DASHBOARD_PORT}" "${RPC_PORT}" "${OFFLINE_MODE}"
    fi
    
    print_message "${GREEN}" "LLM container configuration generated successfully."
  fi
}

# Generate agent templates and training if needed
generate_agent_files() {

  # Setup Umeshian Construct if agents are enabled
  if [ ${INCLUDE_AGENTS} -eq 1 ]; then
    setup_umeshian_construct
  fi
  if [ ${INCLUDE_AGENTS} -eq 1 ]; then
    print_message "${BLUE}" "Generating agent templates and training infrastructure..."
    
    # Generate agent files
    generate_all_agents "${TARGET_DIR}/agents"
    
    print_message "${GREEN}" "Agent templates and training infrastructure generated successfully."
  fi
}

# Copy CLI script to burn folder
copy_cli_script() {
  print_message "${BLUE}" "Installing MCP-ZERO CLI tool..."
  
  # Copy the CLI script
  cp "${SOURCE_DIR}/mcp_cli.sh" "${TARGET_DIR}/mcp-cli.sh"
  chmod +x "${TARGET_DIR}/mcp-cli.sh"
  
  print_message "${GREEN}" "CLI tool installed successfully."
}

# Create a wrapper to enable containerized burn folder environment
create_mcp_integration() {
  print_message "${BLUE}" "Creating MCP integration wrapper..."
  
  # Create an integration script that allows the burn folder to work with MCP-ZERO main project
  cat > "${TARGET_DIR}/integrate_with_mcp.sh" << EOF
#!/bin/bash
# MCP-ZERO Integration Script
# Links this burn folder with the main MCP-ZERO project

set -e

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

# Get the absolute path of this burn folder
BURN_FOLDER="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"

if [ -z "\$1" ]; then
  echo -e "\${RED}Error: Please provide the path to MCP-ZERO main project\${NC}"
  echo "Usage: \$0 /path/to/mcp_zero"
  exit 1
fi

# Get the absolute path of MCP-ZERO main project
MCP_PROJECT="\$(cd "\$1" 2>/dev/null && pwd || echo "")"

if [ -z "\${MCP_PROJECT}" ] || [ ! -d "\${MCP_PROJECT}" ]; then
  echo -e "\${RED}Error: Invalid MCP-ZERO project path\${NC}"
  exit 1
fi

# Check if it's a valid MCP-ZERO project
if [ ! -f "\${MCP_PROJECT}/burn.sh" ]; then
  echo -e "\${RED}Error: Not a valid MCP-ZERO project\${NC}"
  exit 1
fi

echo -e "\${BLUE}Integrating burn folder with MCP-ZERO project...\${NC}"

# Create symbolic links for shared resources
ln -sf "\${MCP_PROJECT}/src" "\${BURN_FOLDER}/src"

# Copy agent models if they exist
if [ -d "\${MCP_PROJECT}/agents/models" ]; then
  echo -e "\${BLUE}Copying agent models...\${NC}"
  rsync -av "\${MCP_PROJECT}/agents/models/" "\${BURN_FOLDER}/agents/models/"
fi

# Set up ZETA components if they exist
if [ -d "\${MCP_PROJECT}/src/zeta_llm" ] || [ -d "\${MCP_PROJECT}/src/zeta_cuda" ]; then
  echo -e "\${BLUE}Setting up ZETA components...\${NC}"
  
  # Create paths configuration
  cat > "\${BURN_FOLDER}/.mcp/config/paths.json" << PATHSEOF
{
  "mcp_project_path": "\${MCP_PROJECT}",
  "zeta_components": {
    "llm_path": "\${MCP_PROJECT}/src/zeta_llm",
    "cuda_path": "\${MCP_PROJECT}/src/zeta_cuda",
    "tensor_path": "\${MCP_PROJECT}/src/zeta_tensor",
    "face_path": "\${MCP_PROJECT}/src/zeta_face"
  }
}
PATHSEOF

  # Update docker-compose to use the right paths
  if [ -f "\${BURN_FOLDER}/docker/docker-compose.llm.yaml" ]; then
    sed -i "s|context: .|context: \${MCP_PROJECT}|g" "\${BURN_FOLDER}/docker/docker-compose.llm.yaml"
  fi
  
  echo -e "\${GREEN}ZETA components configured\${NC}"
fi

# Update configuration to point to the right paths
echo '{"mcp_project_path": "'"\${MCP_PROJECT}"'"}' > "\${BURN_FOLDER}/.mcp/config/paths.json"

# Update docker networks to ensure MCP services can communicate
if [ -f "\${BURN_FOLDER}/docker/docker-compose.yaml" ]; then
  echo -e "\${BLUE}Updating Docker network configuration...\${NC}"
  
  # Create the MCP network if it doesn't exist
  docker network create mcp-network 2>/dev/null || true
  
  # Update the docker-compose files to use the network
  sed -i 's/external: false/external: true/g' "\${BURN_FOLDER}/docker/docker-compose.yaml" 2>/dev/null || true
fi

# Create a convenience script for starting all services
cat > "\${BURN_FOLDER}/start_all.sh" << STARTEOF
#!/bin/bash
# Start all MCP-ZERO services including containers

BURN_FOLDER="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
cd "\${BURN_FOLDER}"

# Start core services
./mcp-cli.sh start all

# Check if we have LLM services
if [ -f "\${BURN_FOLDER}/scripts/start_llm_services.sh" ]; then
  ./scripts/start_llm_services.sh
fi

# Check if we have docker-compose.yaml
if [ -f "\${BURN_FOLDER}/docker/docker-compose.yaml" ]; then
  cd "\${BURN_FOLDER}"
  docker-compose -f docker/docker-compose.yaml up -d
fi

echo -e "All MCP-ZERO services started!"
STARTEOF

chmod +x "\${BURN_FOLDER}/start_all.sh"

# Setup offline-first resilience enforcement
echo -e "\${BLUE}Configuring offline-first resilience...\${NC}"

# Create offline mode toggle script
cat > "\${BURN_FOLDER}/toggle_offline.sh" << OFFLINEOF
#!/bin/bash
# Toggle offline mode for MCP-ZERO

BURN_FOLDER="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"

if [ "\$1" == "enable" ]; then
  echo "Enabling offline mode"
  echo "Offline mode enabled on \$(date -Iseconds)" > "\${BURN_FOLDER}/.mcp/locks/offline.lock"
  chmod 444 "\${BURN_FOLDER}/.mcp/locks/offline.lock"
  echo "Offline mode enabled. Services will use local processing only."
elif [ "\$1" == "disable" ]; then
  if [ -f "\${BURN_FOLDER}/.mcp/locks/offline.lock" ]; then
    if [ "\$(stat -c %a "\${BURN_FOLDER}/.mcp/locks/offline.lock")" == "444" ]; then
      echo "Warning: Offline lock is immutable. You must use sudo to remove it:"
      echo "sudo rm \${BURN_FOLDER}/.mcp/locks/offline.lock"
      exit 1
    else
      rm "\${BURN_FOLDER}/.mcp/locks/offline.lock"
      echo "Offline mode disabled. Services will attempt online connections."
    fi
  else
    echo "Offline mode is not enabled."
  fi
else
  echo "Usage: \$0 enable|disable"
  exit 1
fi
OFFLINEOF

chmod +x "\${BURN_FOLDER}/toggle_offline.sh"

# Implement single connection attempt pattern in docker scripts
echo -e "\${BLUE}Implementing single connection attempt pattern...\${NC}"
if [ -d "\${BURN_FOLDER}/docker" ]; then
  mkdir -p "\${BURN_FOLDER}/docker/scripts"
  cat > "\${BURN_FOLDER}/docker/scripts/single_connection_attempt.sh" << SINGLEOF
#!/bin/bash
# Implement single connection attempt pattern for MCP-ZERO services

# Usage: ./single_connection_attempt.sh HOST PORT TIMEOUT
# Returns 0 if connection successful, 1 if failed

HOST="\$1"
PORT="\$2"
TIMEOUT="\$3"

if [ -z "\$HOST" ] || [ -z "\$PORT" ]; then
  echo "Usage: \$0 HOST PORT [TIMEOUT]"
  exit 1
fi

if [ -z "\$TIMEOUT" ]; then
  TIMEOUT=5
fi

# Try a single connection
if timeout \$TIMEOUT bash -c "cat < /dev/null > /dev/tcp/\$HOST/\$PORT" 2>/dev/null; then
  echo "Connection to \$HOST:\$PORT succeeded"
  exit 0
else
  echo "Connection to \$HOST:\$PORT failed, switching to offline mode"
  exit 1
fi
SINGLEOF

  chmod +x "\${BURN_FOLDER}/docker/scripts/single_connection_attempt.sh"
fi

echo -e "\${GREEN}Integration complete!\${NC}"
echo -e "\${YELLOW}You can now use this burn folder with the MCP-ZERO main project\${NC}"
echo -e "\${YELLOW}Run './start_all.sh' to start all services\${NC}"
EOF

  chmod +x "${TARGET_DIR}/integrate_with_mcp.sh"
  
  print_message "${GREEN}" "MCP integration wrapper created successfully."
}

# Create burn folder README
create_burn_readme() {
  print_message "${BLUE}" "Creating README file..."
  
  local offline_status=$([ "${OFFLINE_MODE}" -eq 1 ] && echo "enabled" || echo "disabled")
  local docker_status=$([ "${INCLUDE_DOCKER}" -eq 1 ] && echo "included" || echo "not included")
  local agents_status=$([ "${INCLUDE_AGENTS}" -eq 1 ] && echo "included" || echo "not included")
  local llm_status=$([ "${INCLUDE_LLM}" -eq 1 ] && echo "included" || echo "not included")
  
  cat > "${TARGET_DIR}/README.md" << EOF
# MCP-ZERO Burn Folder

This is an enterprise-ready MCP-ZERO deployment environment generated on $(date -I).

## Configuration

- Offline mode: ${offline_status}
- Docker configuration: ${docker_status}
- Agent templates and training: ${agents_status}
- LLM container support: ${llm_status}
- API port: ${API_PORT}
- Dashboard port: ${DASHBOARD_PORT}
- RPC port: ${RPC_PORT}

## Directory Structure

- **.mcp/**: Configuration, databases, certificates, and lock files
  - **config/**: JSON configuration files
  - **db/**: SQLite databases
  - **certs/**: TLS certificates
  - **locks/**: Offline mode lock files
- **.server/**: Server configuration files
- **bin/**: Binary executables
- **logs/**: Log files
- **scripts/**: Utility scripts

$([ ${INCLUDE_DOCKER} -eq 1 ] && echo "- **docker/**: Docker configuration files")
$([ ${INCLUDE_AGENTS} -eq 1 ] && echo "- **agents/**: Agent templates, models, and training infrastructure")
$([ ${INCLUDE_LLM} -eq 1 ] && echo "- **scripts/**: LLM startup and management scripts")

## Getting Started

1. Start all services:
   \`\`\`
   ./mcp-cli.sh start all
   \`\`\`
   
   $([ ${INCLUDE_LLM} -eq 1 ] && echo "   For LLM services:\n   \`\`\`\n   ./scripts/start_llm_services.sh\n   \`\`\`")

2. Access the dashboard:
   http://localhost:${DASHBOARD_PORT}

3. API endpoint:
   http://localhost:${API_PORT}/api/v1

4. RPC endpoint:
   localhost:${RPC_PORT}

## Offline Mode

$([ ${OFFLINE_MODE} -eq 1 ] && echo "This environment is configured for offline mode with a permanent lock file." || echo "Offline mode is available but not enabled by default. To enable:")
\`\`\`
./mcp-cli.sh offline enable
\`\`\`

## Documentation

For detailed documentation, see the docs directory in the original MCP-ZERO repository.
EOF

  print_message "${GREEN}" "README file created successfully."
}

# Main execution
# Setup Umeshian Construct integration
setup_umeshian_construct() {
  echo -e "${BLUE}Setting up Umeshian Construct integration...${NC}"
  
  # Create directories if they dont exist
  mkdir -p "${TARGET_DIR}/agents/umeshian_construct/contracts/burned"
  mkdir -p "${TARGET_DIR}/agents/umeshian_construct/scripts"
  mkdir -p "${TARGET_DIR}/agents/umeshian_construct/skills"
  mkdir -p "${TARGET_DIR}/agents/umeshian_construct/models"
  mkdir -p "${TARGET_DIR}/agents/umeshian_construct/data/medical"
  mkdir -p "${TARGET_DIR}/logs/umeshian"
  
  # Copy the medical contract if it exists
  if [ -f "${SOURCE_DIR}/burn_folder/agents/umeshian_construct/contracts/medical_contract.yaml" ]; then
    cp "${SOURCE_DIR}/burn_folder/agents/umeshian_construct/contracts/medical_contract.yaml" \
       "${TARGET_DIR}/agents/umeshian_construct/contracts/medical_contract.yaml"
  fi
  
  # Copy the base contract if it exists
  if [ -f "${SOURCE_DIR}/burn_folder/agents/umeshian_construct/contracts/contract.yaml" ]; then
    cp "${SOURCE_DIR}/burn_folder/agents/umeshian_construct/contracts/contract.yaml" \
       "${TARGET_DIR}/agents/umeshian_construct/contracts/contract.yaml"
  fi
  
  # Create symbolic agent startup script
  cat > "${TARGET_DIR}/start_umeshian_agent.sh" << 'EOF'
#!/bin/bash
# Start the Umeshian Construct symbolic agent

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export MCPZERO_ROOT="${SCRIPT_DIR}"

# Parse arguments
MODE="query"
QUERY=""
DATASET=""

while [[ $# -gt 0 ]]; do
  case $1 in
    --mode)
      MODE="$2"
      shift 2
      ;;
    --query)
      QUERY="$2"
      shift 2
      ;;
    --dataset)
      DATASET="$2"
      shift 2
      ;;
    *)
      echo "Unknown option: $1"
      exit 1
      ;;
  esac
done

echo "Starting Umeshian Construct symbolic agent in ${MODE} mode..."

# Run the appropriate script based on mode
case $MODE in
  query)
    if [ -z "$QUERY" ]; then
      echo "Error: No query provided. Use --query "Your question here""
      exit 1
    fi
    
    echo "Processing query: $QUERY"
    echo "Result: Symbolic agent response would appear here"
    ;;
    
  train)
    if [ -z "$DATASET" ]; then
      echo "Error: No dataset provided. Use --dataset path/to/dataset"
      exit 1
    fi
    
    echo "Training with dataset: $DATASET"
    ;;
    
  status)
    echo "Checking symbolic agent status..."
    echo "Status: READY"
    ;;
    
  *)
    echo "Unknown mode: ${MODE}"
    echo "Available modes: query, train, status"
    exit 1
    ;;
esac
EOF

  chmod +x "${TARGET_DIR}/start_umeshian_agent.sh"
  
  echo -e "${GREEN}Umeshian Construct integration setup complete.${NC}"
}

main() {
  print_message "${BLUE}" "MCP-ZERO Burn Folder Generator"
  print_message "${BLUE}" "==============================="
  
  # Parse command line arguments
  parse_arguments "$@"
  
  # Check dependencies
  check_dependencies
  
  # Create directory structure
  create_directory_structure
  
  # Generate configuration files
  generate_config_files
  
  # Initialize databases
  initialize_databases
  
  # Generate certificates
  generate_certificates
  
  # Generate Docker configuration if needed
  generate_docker_files
  
  # Generate agent templates and training if needed
  generate_agent_files

  # Setup Umeshian Construct if agents are enabled
  if [ ${INCLUDE_AGENTS} -eq 1 ]; then
    setup_umeshian_construct
  fi
  
  # Generate LLM container support if needed
  generate_llm_files
  
  # Copy CLI script
  copy_cli_script
  
  # Create MCP integration wrapper
  create_mcp_integration
  
  # Integrate ZETA playground
  integrate_zeta_playground "${TARGET_DIR}"
  
  # Create README
  create_burn_readme
  
  print_message "${GREEN}" "Burn folder '$(basename ${TARGET_DIR})' created successfully at: ${TARGET_DIR}"
  print_message "${YELLOW}" "Next steps:"
  print_message "${YELLOW}" "1. Review settings in .mcp/config/"
  print_message "${YELLOW}" "2. CD into your burn folder: cd ${TARGET_DIR}"
  print_message "${YELLOW}" "3. Run './mcp-cli.sh start all' to start services"
  if [ ${INCLUDE_AGENTS} -eq 1 ]; then
    print_message "${YELLOW}" "4. Access agent training with './agents/healthcare/playground_adapter.py --mode train'"
  fi
  if [ ${INCLUDE_LLM} -eq 1 ]; then
    print_message "${YELLOW}" "3. Start LLM services with './scripts/start_llm_services.sh'"
  fi
  print_message "${YELLOW}" "4. Access the dashboard at http://localhost:${DASHBOARD_PORT}"
}

main "$@"
