package workload

import (
	"fmt"
	v12 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/apps/v1"
	"github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/core/v1"
	v13 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/meta/v1"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

type DeploymentConfiguration struct {
	Env            map[string]string
	Name           string
	Replicas       int
	ImageReference *ImageReference
}

type ImageReference struct {
	Image  string
	Health string
	Ready  string
}

func (deployment *DeploymentConfiguration) CreateDeployment(
	ctx *pulumi.Context,
	namespace *v1.Namespace,
	parentApplication pulumi.Resource,
	appLabels pulumi.StringMap,
) (*v12.Deployment, error) {
	env := v1.EnvVarArray{}
	for key, value := range deployment.Env {
		env = append(env, &v1.EnvVarArgs{
			Name:  pulumi.String(key),
			Value: pulumi.String(value),
		})
	}

	return v12.NewDeployment(ctx, fmt.Sprintf("%s-deployment", deployment.Name), &v12.DeploymentArgs{
		Metadata: &v13.ObjectMetaArgs{
			Namespace: namespace.Metadata.Name(),
			Labels: pulumi.StringMap{
				"app.kubernetes.io/part-of":    pulumi.String(deployment.Name),
				"app.kubernetes.io/managed-by": pulumi.String("pulumi"),
			},
		},
		Spec: v12.DeploymentSpecArgs{
			Selector: &v13.LabelSelectorArgs{
				MatchLabels: appLabels,
			},
			Replicas: pulumi.Int(deployment.Replicas),
			Template: &v1.PodTemplateSpecArgs{
				Metadata: &v13.ObjectMetaArgs{
					Labels: appLabels,
				},
				Spec: &v1.PodSpecArgs{
					Containers: v1.ContainerArray{
						v1.ContainerArgs{
							Name:  pulumi.String(deployment.Name),
							Image: pulumi.String(deployment.ImageReference.Image),
							Ports: v1.ContainerPortArray{
								v1.ContainerPortArgs{
									Name:          pulumi.String("http"),
									ContainerPort: pulumi.Int(80),
									Protocol:      pulumi.String("TCP"),
								},
							},
							Env: env,
							LivenessProbe: &v1.ProbeArgs{
								HttpGet: &v1.HTTPGetActionArgs{
									Path: pulumi.String(deployment.ImageReference.Health),
									Port: pulumi.Int(80),
								},
								InitialDelaySeconds: pulumi.Int(70),
								PeriodSeconds:       pulumi.Int(15),
							},
							ReadinessProbe: &v1.ProbeArgs{
								HttpGet: &v1.HTTPGetActionArgs{
									Path: pulumi.String(deployment.ImageReference.Ready),
									Port: pulumi.Int(80),
								},
							},
						},
					},
				},
			},
		},
	}, pulumi.Parent(parentApplication))
}
