#!/usr/bin/env python3
"""
Update redtag-prod CircleCI configs with 2-stage approval workflow.
Adds SNS notifications, clean version tags, and proper context/runner.
"""

import os
import re

# Services to update
SERVICES = [
    "tbi-redtag-mobile-hotel-service",
    "tbi-redtag-mobile-ms-activities",
    "tbi-redtag-mobile-ms-bookings",
    "tbi-redtag-mobile-ms-cars",
    "tbi-redtag-mobile-ms-flights",
]

# Template for notify jobs
NOTIFY_BUILD_JOB = """
  notify-await-build-approval:
    executor: aws-cli/default
    resource_class: small
    steps:
      - checkout
      - aws-cli/setup:
          profile_name: default
      - run:
          name: Send SNS notification - Awaiting BUILD approval
          command: |
            BASE_VERSION=$(cat VERSION | tr -d '[:space:]')
            IMAGE_TAG="${BASE_VERSION}"

            cat > /tmp/sns-approval-needed.txt \\<< EOF
            ⏳ PRODUCTION Pipeline - Awaiting BUILD Approval

            Service: SERVICE_NAME
            Environment: PRODUCTION (redtag-prod cluster)
            Build: #${CIRCLE_BUILD_NUM}
            Branch: ${CIRCLE_BRANCH}
            Commit: ${CIRCLE_SHA1:0:7}
            Image Tag: ${IMAGE_TAG}
            Triggered by: ${CIRCLE_USERNAME}

            ✅ Tests have passed successfully

            ⏳ MANUAL APPROVAL REQUIRED to proceed with Docker image build

            To approve:
            1. Go to: ${CIRCLE_BUILD_URL}
            2. Click "Approve" on the approve-build job

            Once approved, the Docker image will be built and pushed to ECR.
            EOF

            aws sns publish \\
              --region ca-central-1 \\
              --topic-arn "arn:aws:sns:ca-central-1:489176460030:DevOps-alert" \\
              --subject "🔒 PROD Approval Needed: BUILD - SERVICE_NAME #${CIRCLE_BUILD_NUM}" \\
              --message file:///tmp/sns-approval-needed.txt

            echo "✓ SNS notification sent - awaiting BUILD approval"
"""

NOTIFY_DEPLOY_JOB = """
  notify-await-deploy-approval:
    executor: aws-cli/default
    resource_class: small
    steps:
      - attach_workspace:
          at: .
      - aws-cli/setup:
          profile_name: default
      - run:
          name: Send SNS notification - Awaiting DEPLOY approval
          command: |
            IMAGE_TAG=$(cat IMAGE_TAG | tr -d '[:space:]')

            cat > /tmp/sns-deploy-approval.txt \\<< EOF
            ⏳ PRODUCTION Pipeline - Awaiting DEPLOY Approval

            Service: SERVICE_NAME
            Environment: PRODUCTION (redtag-prod cluster)
            Namespace: redtag
            Build: #${CIRCLE_BUILD_NUM}
            Branch: ${CIRCLE_BRANCH}
            Commit: ${CIRCLE_SHA1:0:7}
            Image Tag: ${IMAGE_TAG}
            Triggered by: ${CIRCLE_USERNAME}

            ✅ Tests passed
            ✅ Docker image built and pushed to ECR

            ⏳ MANUAL APPROVAL REQUIRED to deploy to PRODUCTION cluster

            To approve:
            1. Go to: ${CIRCLE_BUILD_URL}
            2. Click "Approve" on the approve-deploy job

            ⚠️  WARNING: This will deploy to PRODUCTION redtag-prod Kubernetes cluster!
            ⚠️  Ensure the image has been tested and validated.

            Once approved, the service will be deployed to production.
            EOF

            aws sns publish \\
              --region ca-central-1 \\
              --topic-arn "arn:aws:sns:ca-central-1:489176460030:DevOps-alert" \\
              --subject "🔒 PROD Approval Needed: DEPLOY - SERVICE_NAME #${CIRCLE_BUILD_NUM}" \\
              --message file:///tmp/sns-deploy-approval.txt

            echo "✓ SNS notification sent - awaiting DEPLOY approval"
"""

WORKFLOW_TEMPLATE = """# Workflows
workflows:
  deploy-SERVICE_NAME:
    jobs:
      # Step 1: Run tests
      - lint-and-test:
          context: devops-mgt-prod
          filters:
            branches:
              only:
                - master

      # Step 2: Notify that BUILD approval is needed
      - notify-await-build-approval:
          context: devops-mgt-prod
          requires:
            - lint-and-test
          filters:
            branches:
              only:
                - master

      # Step 3: Manual approval to build (DevOps)
      - approve-build:
          type: approval
          requires:
            - notify-await-build-approval
          filters:
            branches:
              only:
                - master

      # Step 4: Build and push Docker image
      - build-and-push-images:
          context: devops-mgt-prod
          requires:
            - approve-build
          filters:
            branches:
              only:
                - master

      # Step 5: Notify that DEPLOY approval is needed
      - notify-await-deploy-approval:
          context: devops-mgt-prod
          requires:
            - build-and-push-images
          filters:
            branches:
              only:
                - master

      # Step 6: Manual approval to deploy (DevOps)
      - approve-deploy:
          type: approval
          requires:
            - notify-await-deploy-approval
          filters:
            branches:
              only:
                - master

      # Step 7: Deploy to production Kubernetes
      - deploy-to-kubernetes:
          context: devops-mgt-prod
          requires:
            - approve-deploy
          filters:
            branches:
              only:
                - master
"""


def update_service(service_name):
    """Update a single service config."""
    config_path = f"redtag-prod/{service_name}/.circleci/config.yml"
    
    if not os.path.exists(config_path):
        print(f"❌ Config not found: {config_path}")
        return False
    
    print(f"Updating {service_name}...")
    
    with open(config_path, 'r') as f:
        content = f.read()
    
    # 1. Update runner to prod-win
    content = re.sub(
        r'resource_class: tbi-local-runner/loadtest',
        'resource_class: tbi-local-runner/prod-win',
        content
    )
    
    # 2. Update image tag generation to use clean tags for production
    old_tag_gen = r'''      - run:
          name: Generate image tags
          command: \|
            BASE_VERSION=\$\(cat VERSION \| tr -d '\[:space:\]'\)
            IMAGE_TAG="\$\{BASE_VERSION\}-\$\{CIRCLE_BRANCH\}-\$\{CIRCLE_BUILD_NUM\}"
            echo "export IMAGE_TAG=\$\{IMAGE_TAG\}" >> \$BASH_ENV
            echo "\$\{IMAGE_TAG\}" > IMAGE_TAG
            echo "Image tag: \$\{IMAGE_TAG\}"'''
    
    new_tag_gen = '''      - run:
          name: Generate image tags
          command: |
            BASE_VERSION=$(cat VERSION | tr -d '[:space:]')
            # Production uses clean version tag (no branch/build suffix)
            if [ "${CIRCLE_BRANCH}" == "master" ] || [ "${CIRCLE_BRANCH}" == "main" ]; then
              IMAGE_TAG="${BASE_VERSION}"
              echo "🔒 PRODUCTION: Using clean version tag: ${IMAGE_TAG}"
            else
              IMAGE_TAG="${BASE_VERSION}-${CIRCLE_BRANCH}-${CIRCLE_BUILD_NUM}"
              echo "Image tag: ${IMAGE_TAG}"
            fi
            echo "export IMAGE_TAG=${IMAGE_TAG}" >> $BASH_ENV
            echo "${IMAGE_TAG}" > IMAGE_TAG'''
    
    content = re.sub(old_tag_gen, new_tag_gen, content, flags=re.MULTILINE)
    
    # 3. Add DEPLOY_ENV validation and SNS notifications to deploy job
    old_deploy_step = r'''      - run:
          name: Package Helm charts, update requirements, and deploy
          command: \|
            chmod \+x scripts/deploy-services\.sh
            bash scripts/deploy-services\.sh'''
    
    new_deploy_step = f'''      - run:
          name: Package Helm charts, update requirements, and deploy
          command: |
            # Verify DEPLOY_ENV is set from CircleCI context
            if [ -z "${{DEPLOY_ENV}}" ]; then
              echo "ERROR: DEPLOY_ENV not set in CircleCI context!"
              echo "Expected DEPLOY_ENV=redtag-prod from devops-mgt-prod context"
              exit 1
            fi

            echo "DEPLOY_ENV is set to: ${{DEPLOY_ENV}}"

            # Verify it matches expected value for PRODUCTION
            if [ "${{DEPLOY_ENV}}" != "redtag-prod" ]; then
              echo "WARNING: DEPLOY_ENV=${{DEPLOY_ENV}} but expected 'redtag-prod' for PRODUCTION deployment"
              echo "This will deploy to ${{DEPLOY_ENV}}/values/ instead of redtag-prod/values/"
              exit 1
            fi

            chmod +x scripts/deploy-services.sh
            bash scripts/deploy-services.sh
      - run:
          name: Send deployment success notification
          command: |
            IMAGE_TAG=$(cat IMAGE_TAG | tr -d '[:space:]')

            cat > /tmp/sns-message.txt \\<< EOF
            ✅ Deployment Successful - {service_name}

            Environment: ${{DEPLOY_ENV}}
            Namespace: redtag
            Image Tag: ${{IMAGE_TAG}}
            Build: #${{CIRCLE_BUILD_NUM}}
            Branch: ${{CIRCLE_BRANCH}}
            Commit: ${{CIRCLE_SHA1:0:7}}
            Triggered by: ${{CIRCLE_USERNAME}}

            View build: ${{CIRCLE_BUILD_URL}}
            EOF

            aws sns publish \\
              --region ca-central-1 \\
              --topic-arn "arn:aws:sns:ca-central-1:489176460030:DevOps-alert" \\
              --subject "DevOps CI/CD Pipeline Notification" \\
              --message file:///tmp/sns-message.txt

            echo "✓ Deployment success notification sent"
      - run:
          name: Send deployment failure notification
          when: on_fail
          command: |
            IMAGE_TAG=$(cat IMAGE_TAG 2>/dev/null | tr -d '[:space:]' || echo "unknown")

            cat > /tmp/sns-failure.txt \\<< EOF
            ❌ Deployment Failed - {service_name}

            Environment: ${{DEPLOY_ENV}}
            Namespace: redtag
            Image Tag: ${{IMAGE_TAG}}
            Build: #${{CIRCLE_BUILD_NUM}}
            Branch: ${{CIRCLE_BRANCH}}
            Commit: ${{CIRCLE_SHA1:0:7}}
            Triggered by: ${{CIRCLE_USERNAME}}

            View build: ${{CIRCLE_BUILD_URL}}

            Please check the build logs for error details.
            EOF

            aws sns publish \\
              --region ca-central-1 \\
              --topic-arn "arn:aws:sns:ca-central-1:489176460030:DevOps-alert" \\
              --subject "DevOps CI/CD Pipeline Notification" \\
              --message file:///tmp/sns-failure.txt

            echo "✓ Deployment failure notification sent"'''
    
    content = re.sub(old_deploy_step, new_deploy_step, content, flags=re.MULTILINE)
    
    # 4. Add notify jobs before workflows
    notify_build = NOTIFY_BUILD_JOB.replace("SERVICE_NAME", service_name)
    notify_deploy = NOTIFY_DEPLOY_JOB.replace("SERVICE_NAME", service_name)
    
    # Find the position before workflows
    workflow_pos = content.find("# Workflows")
    if workflow_pos == -1:
        print(f"❌ Could not find workflows section in {service_name}")
        return False
    
    # Insert notify jobs
    content = content[:workflow_pos] + notify_build + "\n" + notify_deploy + "\n" + content[workflow_pos:]
    
    # 5. Replace workflow with approval workflow
    workflow_pattern = r'# Workflows\nworkflows:.*'
    new_workflow = WORKFLOW_TEMPLATE.replace("SERVICE_NAME", service_name)
    content = re.sub(workflow_pattern, new_workflow, content, flags=re.DOTALL)
    
    # Write updated content
    with open(config_path, 'w') as f:
        f.write(content)
    
    print(f"✅ Updated {service_name}")
    return True


def main():
    """Update all redtag-prod services."""
    print("=" * 60)
    print("Updating redtag-prod CircleCI configs")
    print("=" * 60)
    
    success_count = 0
    for service in SERVICES:
        if update_service(service):
            success_count += 1
        print()
    
    print("=" * 60)
    print(f"✅ Successfully updated {success_count}/{len(SERVICES)} services")
    print("=" * 60)


if __name__ == "__main__":
    main()
