import * as cdk from "aws-cdk-lib";
import { Rule } from "aws-cdk-lib/aws-events";
import { SnsTopic } from "aws-cdk-lib/aws-events-targets";
import { AnyPrincipal, Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
import { Key } from "aws-cdk-lib/aws-kms";
import { Topic } from "aws-cdk-lib/aws-sns";
import { StringParameter } from "aws-cdk-lib/aws-ssm";
import { Construct } from "constructs";

export interface HealthAlertStackProps extends cdk.StackProps {
  readonly topicName: string;
}

export class HealthAlertStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: HealthAlertStackProps) {
    super(scope, id, props);

    const { topicName } = props;

    const key = new Key(this, "HealthAlertTopicKey", {
      alias: `alias/${topicName}-key`,
      description: "Key for health alert topic",
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });
    key.addToResourcePolicy(
      new PolicyStatement({
        effect: Effect.ALLOW,
        principals: [new AnyPrincipal()],
        actions: ["kms:Decrypt", "kms:GenerateDataKey*"],
        resources: ["*"],
      }),
    );

    const topic = new Topic(this, "HealthAlertTopic", {
      topicName,
      masterKey: key,
    });
    topic.addToResourcePolicy(
      new PolicyStatement({
        sid: "SNSPublishingPermissions",
        effect: Effect.ALLOW,
        principals: [new AnyPrincipal()],
        actions: ["sns:Publish"],
        resources: [topic.topicArn],
      }),
    );

    new StringParameter(this, "ParamStageAlertTopicArn", {
      parameterName: `/account/health-alert-topic-arn`,
      stringValue: topic.topicArn,
    });

    // Health Alert
    const healthRule = new Rule(this, "HealthRule", {
      eventPattern: {
        source: ["aws.health"],
        detailType: ["AWS Health Event"],
      },
    });
    healthRule.addTarget(new SnsTopic(topic));
  }
}
