#!/bin/bash

# Deployment workflow script for Device Management System
# This script deploys all components in the correct order

set -e  # Exit on error

# Function to display section headers
section() {
  echo ""
  echo "=========================================="
  echo "  $1"
  echo "=========================================="
  echo ""
}

# Function to check if a command exists
command_exists() {
  command -v "$1" >/dev/null 2>&1
}

# Check prerequisites
section "Checking prerequisites"

# Check for AWS CLI
if ! command_exists aws; then
  echo "Error: AWS CLI is not installed. Please install it first."
  exit 1
fi

# Check for Python
if ! command_exists python; then
  echo "Error: Python is not installed. Please install Python 3.8 or higher."
  exit 1
fi

# Check for pip
if ! command_exists pip; then
  echo "Error: pip is not installed. Please install it first."
  exit 1
fi

# Check AWS credentials
if ! aws sts get-caller-identity >/dev/null 2>&1; then
  echo "Error: AWS credentials not configured or invalid. Please run 'aws configure'."
  exit 1
fi

echo "All prerequisites satisfied."

# Step 1: Deploy Device Management Lambda
section "Step 1: Deploying Device Management Lambda"

cd device-management
echo "Installing Python dependencies..."
pip install -r requirements.txt

echo "Deploying Lambda function..."
chmod +x deploy.sh
./deploy.sh

# Get the Lambda ARN from the output file or AWS CLI
if [ -f lambda_arn.txt ]; then
  LAMBDA_ARN=$(grep LAMBDA_ARN lambda_arn.txt | cut -d= -f2)
  echo "Lambda ARN: $LAMBDA_ARN"
else
  # Fallback: get Lambda ARN directly from AWS
  LAMBDA_FUNCTION_NAME=${LAMBDA_FUNCTION_NAME:-"DeviceManagementLambda"}
  LAMBDA_ARN=$(aws lambda get-function --function-name "$LAMBDA_FUNCTION_NAME" --region us-west-2 --query 'Configuration.FunctionArn' --output text 2>/dev/null)
  if [ -z "$LAMBDA_ARN" ]; then
    echo "Error: Lambda ARN not found. Please ensure the Lambda function was deployed successfully."
    exit 1
  fi
  echo "Lambda ARN (from AWS): $LAMBDA_ARN"
fi

cd ..

# Step 2: Create Gateway
section "Step 2: Creating Gateway"

cd gateway

# Check if .env file exists, if not create it
if [ ! -f .env ]; then
  echo "Creating .env file for gateway..."
  
  # Create basic .env file structure
  cat > .env << EOF
# AWS and endpoint configuration
AWS_REGION=us-west-2
ENDPOINT_URL=https://bedrock-agentcore-control.us-west-2.amazonaws.com

# Lambda configuration (from device-management module)
LAMBDA_ARN=$LAMBDA_ARN

# Target configuration
GATEWAY_IDENTIFIER=your-gateway-identifier
TARGET_NAME=device-management-target
TARGET_DESCRIPTION=List, Update device management activities

# Gateway creation configuration
GATEWAY_NAME=Device-Management-Gateway
GATEWAY_DESCRIPTION=Device Management Gateway
EOF
  
  echo "Please edit the gateway/.env file to set your Cognito details and other required values."
  echo "Then run this script again."
  exit 0
else
  # Update existing .env file with Lambda ARN
  echo "Updating existing .env file with Lambda ARN..."
  if grep -q "^LAMBDA_ARN=" .env; then
    # Update existing LAMBDA_ARN line
    if [[ "$OSTYPE" == "darwin"* ]]; then
      sed -i '' "s|^LAMBDA_ARN=.*|LAMBDA_ARN=$LAMBDA_ARN|g" .env
    else
      sed -i "s|^LAMBDA_ARN=.*|LAMBDA_ARN=$LAMBDA_ARN|g" .env
    fi
  else
    # Add LAMBDA_ARN to the file
    echo "" >> .env
    echo "# Lambda configuration (from device-management module)" >> .env
    echo "LAMBDA_ARN=$LAMBDA_ARN" >> .env
  fi
fi

echo "Creating gateway..."
python create_gateway.py

# Get the Gateway ID from the output
GATEWAY_NAME=$(grep GATEWAY_NAME .env | cut -d= -f2)
GATEWAY_ID=$(aws bedrock-agentcore list-gateways --query "gateways[?name=='$GATEWAY_NAME'].gatewayId" --output text)

if [ -z "$GATEWAY_ID" ]; then
  echo "Error: Failed to get Gateway ID."
  exit 1
fi

echo "Gateway ID: $GATEWAY_ID"

# Update the .env file with the Gateway ID
if [[ "$OSTYPE" == "darwin"* ]]; then
  sed -i '' "s|GATEWAY_IDENTIFIER=.*|GATEWAY_IDENTIFIER=$GATEWAY_ID|g" .env
else
  sed -i "s|GATEWAY_IDENTIFIER=.*|GATEWAY_IDENTIFIER=$GATEWAY_ID|g" .env
fi

echo "Creating gateway target..."
python device-management-target.py

# Update .env with Gateway ARN and ID for observability
GATEWAY_ARN=$(aws bedrock-agentcore list-gateways --query "gateways[?gatewayId=='$GATEWAY_ID'].gatewayArn" --output text)
if ! grep -q "^GATEWAY_ARN=" .env; then
  echo "GATEWAY_ARN=$GATEWAY_ARN" >> .env
fi
if ! grep -q "^GATEWAY_ID=" .env; then
  echo "GATEWAY_ID=$GATEWAY_ID" >> .env
fi

echo "Setting up gateway observability..."
python gateway_observability.py

cd ..

# Step 3: Deploy Agent Runtime
section "Step 3: Deploying Agent Runtime"

cd agent-runtime

# Check if .env file exists, if not create it
if [ ! -f .env ]; then
  echo "Creating .env file for agent runtime..."
  cp .env.example .env
  
  # Update the Gateway URL in the .env file
  GATEWAY_URL="https://$GATEWAY_ID.gateway.bedrock-agentcore.us-west-2.amazonaws.com"
  if [[ "$OSTYPE" == "darwin"* ]]; then
    sed -i '' "s|MCP_SERVER_URL=.*|MCP_SERVER_URL=$GATEWAY_URL|g" .env
  else
    sed -i "s|MCP_SERVER_URL=.*|MCP_SERVER_URL=$GATEWAY_URL|g" .env
  fi
  
  echo "Please edit the agent-runtime/.env file to set your Cognito details and other required values."
  echo "Then run this script again."
  exit 0
fi

# Update requirements-runtime.txt with observability packages
echo "Updating requirements-runtime.txt with observability packages..."
if ! grep -q "aws_opentelemetry_distro_genai_beta" requirements-runtime.txt; then
  echo "aws_opentelemetry_distro_genai_beta>=0.1.2" >> requirements-runtime.txt
fi
if ! grep -q "aws-xray-sdk" requirements-runtime.txt; then
  echo "aws-xray-sdk>=2.12.0" >> requirements-runtime.txt
fi
if ! grep -q "watchtower" requirements-runtime.txt; then
  echo "watchtower>=3.0.1" >> requirements-runtime.txt
fi
if ! grep -q "opentelemetry-instrumentation-requests" requirements-runtime.txt; then
  echo "opentelemetry-instrumentation-requests>=0.40b0" >> requirements-runtime.txt
fi
if ! grep -q "opentelemetry-instrumentation-boto3" requirements-runtime.txt; then
  echo "opentelemetry-instrumentation-boto3>=0.40b0" >> requirements-runtime.txt
fi

# Update Dockerfile with OpenTelemetry configuration
echo "Updating Dockerfile with OpenTelemetry configuration..."
cat > Dockerfile << 'EOF'
FROM public.ecr.aws/docker/library/python:3.12-slim
WORKDIR /app

# Copy entire project (respecting .dockerignore)
COPY . .

# Install dependencies
RUN python -m pip install --no-cache-dir -r requirements-runtime.txt

# Install AWS OpenTelemetry Distro for GenAI
RUN python -m pip install aws_opentelemetry_distro_genai_beta>=0.1.2

# Install AWS X-Ray SDK
RUN python -m pip install aws-xray-sdk

# Set AWS region environment variable
ENV AWS_REGION=us-west-2
ENV AWS_DEFAULT_REGION=us-west-2

# Set OpenTelemetry environment variables
ENV OTEL_PYTHON_DISABLED_INSTRUMENTATIONS=""
ENV OTEL_METRICS_EXPORTER="otlp"
ENV OTEL_TRACES_EXPORTER="otlp"
ENV OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
ENV OTEL_RESOURCE_ATTRIBUTES="service.name=device-management-agent"

# Signal that this is running in Docker for host binding logic
ENV DOCKER_CONTAINER=1

# Create non-root user
RUN useradd -m -u 1000 bedrock_agentcore
USER bedrock_agentcore

EXPOSE 8080

# Use OpenTelemetry instrumentation to run the application
CMD ["opentelemetry-instrument", "python3.12", "-m", "strands-agent-runtime"]
EOF

# Update .bedrock_agentcore.yaml to ensure observability is enabled
echo "Ensuring observability is enabled in .bedrock_agentcore.yaml..."
if [ -f .bedrock_agentcore.yaml ]; then
  # Check if observability section exists and update it
  if grep -q "observability:" .bedrock_agentcore.yaml; then
    # Use awk to update the observability section
    awk '
    /observability:/ {
      print "      observability:";
      print "        enabled: true";
      print "        cloudwatch:";
      print "          log_group: \"/aws/bedrock-agentcore/device-management-agent\"";
      print "        xray:";
      print "          trace_enabled: true";
      found=1;
      next;
    }
    /enabled:/ && found==1 { found=0; next; }
    found==1 { next; }
    { print }
    ' .bedrock_agentcore.yaml > .bedrock_agentcore.yaml.tmp && mv .bedrock_agentcore.yaml.tmp .bedrock_agentcore.yaml
  fi
fi

echo "Installing Python dependencies for agent runtime..."
pip install -r requirements-runtime.txt

echo "Deploying agent runtime..."
python strands_agent_runtime_deploy.py

cd ..

# Step 4: Update frontend configuration
section "Step 4: Updating frontend configuration"

# Get the Gateway URL
GATEWAY_URL="https://$GATEWAY_ID.gateway.bedrock-agentcore.us-west-2.amazonaws.com"
echo "Gateway URL: $GATEWAY_URL"

# Create .env file for frontend if it doesn't exist
if [ ! -f frontend/.env ]; then
  echo "Creating .env file for frontend..."
  echo "MCP_SERVER_URL=$GATEWAY_URL" > frontend/.env
  echo "COGNITO_DOMAIN=$(grep FRONTEND_COGNITO_DOMAIN .env | cut -d= -f2)" >> frontend/.env
  echo "COGNITO_CLIENT_ID=$(grep FRONTEND_COGNITO_APP_CLIENT_ID .env | cut -d= -f2)" >> frontend/.env
  
  echo "Please complete the frontend/.env file with any missing values."
fi

# Step 5: Move chat_app_bedrock to frontend directory
section "Step 5: Moving chat_app_bedrock to frontend directory"

if [ -d chat_app_bedrock ] && [ ! -d frontend/chat_app_bedrock ]; then
  echo "Moving chat_app_bedrock to frontend directory..."
  mv chat_app_bedrock frontend/
fi

section "Deployment completed successfully!"
echo "Next steps:"
echo "1. Generate synthetic data: cd device-management && python synthetic_data.py"
echo "2. Set up the frontend: Follow instructions in frontend/README.md"
echo "3. Test the system: Use the Q CLI or the chat application to interact with the MCP server"
echo "4. Monitor the system: Check CloudWatch Logs and X-Ray traces for observability data"
echo ""
echo "Gateway URL: $GATEWAY_URL"
echo ""
echo "Observability Information:"
echo "- CloudWatch Log Group: /aws/bedrock-agentcore/device-management-agent"
echo "- X-Ray Traces: Enabled for the agent runtime"
echo "- Metrics: Available in CloudWatch Metrics under the 'device-management-agent' namespace"
echo ""
echo "To view logs: https://console.aws.amazon.com/cloudwatch/home?region=us-west-2#logsV2:log-groups"
echo "To view traces: https://console.aws.amazon.com/xray/home?region=us-west-2#/traces"
