import * as cdk from "aws-cdk-lib";
import * as route53 from "aws-cdk-lib/aws-route53";
import * as ssm from "aws-cdk-lib/aws-ssm";
import { Construct } from "constructs";
import { Context } from "../lib/context";

interface StackProps extends cdk.StackProps {
  readonly stage: string;
  readonly domainProps: Context["domainProps"];
}

export class DomainStack extends cdk.Stack {
  public readonly hostedZone: route53.IHostedZone;

  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const { stage, domainProps } = props;

    const accountHostedZoneId = ssm.StringParameter.valueForStringParameter(this, "/account/hosted-zone-id");
    const accountHostedZoneName = ssm.StringParameter.valueForStringParameter(this, "/account/hosted-zone-name");

    const parentHostedZone = route53.PublicHostedZone.fromHostedZoneAttributes(this, "ParentHostedZone", {
      hostedZoneId: accountHostedZoneId,
      zoneName: accountHostedZoneName,
    });

    let hostedZone: route53.IHostedZone;

    if (domainProps.enableSubDomain) {
      hostedZone = new route53.PublicHostedZone(this, "HostedZone", {
        zoneName: `${stage}.${parentHostedZone.zoneName}`,
      });
      new route53.ZoneDelegationRecord(this, "ZoneDelegationRecord", {
        zone: parentHostedZone,
        recordName: stage,
        nameServers: hostedZone.hostedZoneNameServers as string[],
      });
    } else {
      hostedZone = parentHostedZone;
    }

    new ssm.StringParameter(this, "HostedZoneIdParameter", {
      parameterName: `/${stage}/hosted-zone-id`,
      stringValue: hostedZone.hostedZoneId,
    });
    new ssm.StringParameter(this, "HostedZoneNameParameter", {
      parameterName: `/${stage}/hosted-zone-name`,
      stringValue: hostedZone.zoneName,
    });

    this.hostedZone = hostedZone;
  }
}
