import * as cdk from "@aws-cdk/core";
import { Bucket } from "@aws-cdk/aws-s3";
import { EnvName } from "../../env-names";
import { Duration, RemovalPolicy } from "@aws-cdk/core";
import {
  ArnPrincipal,
  Effect,
  PolicyStatement,
  ServicePrincipal,
} from "@aws-cdk/aws-iam";

export interface LoadBalancerAccessLogsBucketProps {
  readonly envName: EnvName;
}

export class LoadBalancerAccessLogsBucket extends cdk.Construct {
  constructor(
    scope: cdk.Construct,
    id: string,
    props: LoadBalancerAccessLogsBucketProps
  ) {
    super(scope, id);
    const stack = cdk.Stack.of(this);
    const accountID = stack.account;

    const removalPolicy =
      props.envName == EnvName.Production
        ? RemovalPolicy.RETAIN
        : RemovalPolicy.DESTROY;

    const bucket = new Bucket(this, "Bucket", {
      bucketName: `load-balancer-access-logs-${accountID}`,
      lifecycleRules: [
        {
          expiration: Duration.days(120),
        },
      ],
      removalPolicy,
    });

    // Add the bucket policy needed to allow the load balancer to write to the bucket.
    // https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-logging-bucket-permissions
    bucket.addToResourcePolicy(
      new PolicyStatement({
        effect: Effect.ALLOW,
        principals: [new ArnPrincipal(`arn:aws:iam::797873946194:root`)],
        actions: ["s3:PutObject"],
        resources: [bucket.arnForObjects(`AWSLogs/${accountID}/*`)],
      })
    );
    bucket.addToResourcePolicy(
      new PolicyStatement({
        effect: Effect.ALLOW,
        principals: [new ServicePrincipal("delivery.logs.amazonaws.com")],
        actions: ["s3:PutObject"],
        resources: [bucket.arnForObjects(`AWSLogs/${accountID}/*`)],
        conditions: {
          StringEquals: {
            "s3:x-amz-acl": "bucket-owner-full-control",
          },
        },
      })
    );
    bucket.addToResourcePolicy(
      new PolicyStatement({
        effect: Effect.ALLOW,
        principals: [new ServicePrincipal("delivery.logs.amazonaws.com")],
        actions: ["s3:GetBucketAcl"],
        resources: [bucket.bucketArn],
      })
    );
  }
}
