#!/usr/bin/env bash
set -euo pipefail

TARGET_ROOT="${1:-.}"

mkdir -p "$TARGET_ROOT/deploy/aws-cloud-scanner"
cat > "$TARGET_ROOT/deploy/aws-cloud-scanner/app.py" <<'EOF'
#!/usr/bin/env python3
"""CDK app entry point for BlackShield Cloud Scanner (AWS Lambda)."""

import os

import aws_cdk as cdk

from cloud_scanner_stack import CloudScannerStack

app = cdk.App()

env = cdk.Environment(
    account=os.environ.get("CDK_DEFAULT_ACCOUNT"),
    region=os.environ.get("CDK_DEFAULT_REGION", "us-east-1"),
)

CloudScannerStack(
    app,
    app.node.try_get_context("stack_name") or "BlackShieldCloudScanner",
    env=env,
    schedule_cron=(app.node.try_get_context("schedule_cron") or "0 */6 * * ? *"),
    blackshield_api_url=(
        app.node.try_get_context("api_url") or os.environ["BLACKSHIELD_API_URL"]
    ),
    secret_name=(
        app.node.try_get_context("secret_name")
        or os.environ.get("SECRET_NAME", "blackshield/cloud-scanner/api-key")
    ),
    scanner_image_uri=(
        app.node.try_get_context("image_uri") or os.environ["SCANNER_IMAGE_URI"]
    ),
)

cdk.Tags.of(app).add("Project", "SecurityPlatform")
cdk.Tags.of(app).add("ManagedBy", "CDK")
cdk.Tags.of(app).add("Component", "cloud-scanner")

app.synth()
EOF

mkdir -p "$TARGET_ROOT/deploy/aws-cloud-scanner"
cat > "$TARGET_ROOT/deploy/aws-cloud-scanner/cdk.json" <<'EOF'
{
  "app": "python app.py",
  "context": {
    "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
    "@aws-cdk/core:checkSecretUsage": true,
    "@aws-cdk/aws-iam:minimizePolicies": true
  }
}
EOF

mkdir -p "$TARGET_ROOT/deploy/aws-cloud-scanner"
cat > "$TARGET_ROOT/deploy/aws-cloud-scanner/cloud_scanner_stack.py" <<'EOF'
"""CDK stack for the BlackShield cloud scanner on AWS."""

from aws_cdk import (
    Duration,
    RemovalPolicy,
    Size,
    Stack,
    aws_events as events,
    aws_events_targets as targets,
    aws_iam as iam,
    aws_lambda as lambda_,
    aws_logs as logs,
    aws_secretsmanager as secretsmanager,
)
from constructs import Construct


class CloudScannerStack(Stack):
    """Deploy a tenant-owned cloud scanner as Lambda plus EventBridge."""

    def __init__(
        self,
        scope: Construct,
        construct_id: str,
        schedule_cron: str,
        blackshield_api_url: str,
        secret_name: str,
        scanner_image_uri: str,
        **kwargs: object,
    ) -> None:
        super().__init__(scope, construct_id, **kwargs)

        role = iam.Role(
            self,
            "ScannerRole",
            assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
            description="BlackShield cloud scanner role",
            managed_policies=[
                iam.ManagedPolicy.from_aws_managed_policy_name(
                    "service-role/AWSLambdaBasicExecutionRole"
                ),
                iam.ManagedPolicy.from_aws_managed_policy_name("SecurityAudit"),
                iam.ManagedPolicy.from_aws_managed_policy_name(
                    "job-function/ViewOnlyAccess"
                ),
            ],
        )

        secret = secretsmanager.Secret.from_secret_name_v2(
            self, "ApiKeySecret", secret_name
        )
        secret.grant_read(role)

        log_group = logs.LogGroup(
            self,
            "ScannerLogs",
            log_group_name=f"/aws/lambda/{construct_id}",
            retention=logs.RetentionDays.ONE_MONTH,
            removal_policy=RemovalPolicy.DESTROY,
        )

        function = lambda_.DockerImageFunction(
            self,
            "CloudScannerFunction",
            function_name=construct_id,
            code=lambda_.DockerImageCode.from_image_uri(scanner_image_uri),
            role=role,
            timeout=Duration.minutes(14),
            memory_size=3072,
            ephemeral_storage_size=Size.gibibytes(2),
            log_group=log_group,
            environment={
                "BLACKSHIELD_API_URL": blackshield_api_url,
                "BLACKSHIELD_API_KEY": secret.secret_value.unsafe_unwrap(),
                "CLOUD_PROVIDER": "aws",
                "SCAN_INTERVAL_SECONDS": "0",
                "SCAN_ON_STARTUP": "true",
                "LOG_LEVEL": "INFO",
                "BATCH_SIZE": "500",
            },
        )

        parts = schedule_cron.split()
        rule = events.Rule(
            self,
            "ScanSchedule",
            description="Trigger BlackShield cloud scanner",
            schedule=events.Schedule.cron(
                minute=parts[0],
                hour=parts[1],
                day=parts[2] if len(parts) > 2 else "*",
                month=parts[3] if len(parts) > 3 else "*",
                week_day=parts[4] if len(parts) > 4 else "?",
            ),
        )
        rule.add_target(targets.LambdaFunction(function))
EOF

mkdir -p "$TARGET_ROOT/deploy/aws-cloud-scanner"
cat > "$TARGET_ROOT/deploy/aws-cloud-scanner/requirements.txt" <<'EOF'
aws-cdk-lib>=2.130.0
constructs>=10.0.0
EOF

printf "Wrote source bundle files:
"
printf "  - %s\n" "$TARGET_ROOT/deploy/aws-cloud-scanner/app.py"
printf "  - %s\n" "$TARGET_ROOT/deploy/aws-cloud-scanner/cdk.json"
printf "  - %s\n" "$TARGET_ROOT/deploy/aws-cloud-scanner/cloud_scanner_stack.py"
printf "  - %s\n" "$TARGET_ROOT/deploy/aws-cloud-scanner/requirements.txt"
