package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/route53"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
)

type Config struct {
	EKSCluster EKSCluster `json:"eksCluster,omitempty" yaml:"eksCluster"`
	Route53    Route53    `json:"route53,omitempty" yaml:"route53"`
}

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		// 0. read config
		conf := config.New(ctx, "")
		c := Config{}
		conf.RequireObject("config", &c)

		// 1. eks cluster
		err := NewEKSCluster(ctx, c.EKSCluster)
		if err != nil {
			return err
		}

		// 2. route53
		err = NewRoute53(ctx, c.Route53)
		if err != nil {
			return err
		}

		return nil
	})
}

type Route53 struct {
	HostedZoneName string `json:"hostedZoneName,omitempty" yaml:"hostedZoneName"`
	AssociatedVPCs []struct {
		VPCID     string `json:"vpcID,omitempty" yaml:"vpcID"`
		VPCRegion string `json:"vpcRegion,omitempty" yaml:"vpcRegion"`
	} `json:"associatedVPCs,omitempty" yaml:"associatedVPCs"`

	DNSRecords []struct {
		Name    string   `json:"name,omitempty" yaml:"name"`
		Type    string   `json:"type,omitempty" yaml:"type"`
		Records []string `json:"records,omitempty" yaml:"records"`
	} `json:"dnsRecords,omitempty" yaml:"dnsRecords"`
}

// NewRoute53 creates DNS records to route53
func NewRoute53(ctx *pulumi.Context, c Route53) error {
	// 1. hosted zone
	var associatedVPCs route53.ZoneVpcArray
	for _, vpc := range c.AssociatedVPCs {
		associatedVPCs = append(associatedVPCs, route53.ZoneVpcArgs{
			VpcId:     pulumi.String(vpc.VPCID),
			VpcRegion: pulumi.String(vpc.VPCRegion),
		})
	}

	zone, err := route53.NewZone(ctx, c.HostedZoneName, &route53.ZoneArgs{
		ForceDestroy: pulumi.BoolPtr(true),
		Name:         pulumi.StringPtr(c.HostedZoneName),
		Vpcs:         route53.ZoneVpcArray(associatedVPCs),
	})
	if err != nil {
		return err
	}

	// 2. records in zone
	for _, record := range c.DNSRecords {
		_, err = route53.NewRecord(ctx, record.Name, &route53.RecordArgs{
			ZoneId:  zone.ID(),
			Name:    pulumi.String(record.Name),
			Type:    pulumi.String(record.Type),
			Records: pulumi.ToStringArray(record.Records),
			Ttl:     pulumi.IntPtr(3600),
		})
		if err != nil {
			return err
		}
	}

	return nil
}
