package cert

import (
	v1 "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
	cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/tidbcloud/infra-provider/pkg/consts"
)

const (
	tidbComponentSelfSignedCACertSecretName = "tidb-components-self-signed-ca-cert"
	SelfSignedCAIssuerName                  = "selfsigned-ca-issuer"
	selfSignedCAIssuerKind                  = v1.ClusterIssuerKind
)

// SelfSignedCAClusterIssuer returns a ClusterIssuer which is used to sign the cluster CA certificate
func SelfSignedCAClusterIssuer() *v1.ClusterIssuer {
	return &v1.ClusterIssuer{
		ObjectMeta: metav1.ObjectMeta{
			Name: SelfSignedCAIssuerName,
		},
		Spec: v1.IssuerSpec{
			IssuerConfig: v1.IssuerConfig{
				SelfSigned: &v1.SelfSignedIssuer{},
			},
		},
	}
}

// SelfSigned returns a Certificate which is the cluster CA certificate
func SelfSignedComponentCACertificate(ns string) *v1.Certificate {
	return &v1.Certificate{
		ObjectMeta: metav1.ObjectMeta{
			Name:      TiDBComponentsSelfSignedCACertName,
			Namespace: ns,
		},
		Spec: v1.CertificateSpec{
			SecretName:  tidbComponentSelfSignedCACertSecretName,
			CommonName:  "TiDB Components Self Signed CA",
			IsCA:        true,
			Duration:    &metav1.Duration{Duration: consts.SelfSignedComponentCACertDuration},
			RenewBefore: &metav1.Duration{Duration: consts.RenewBefore},
			PrivateKey: &v1.CertificatePrivateKey{
				// Rotate both the private key and the certificate.
				// See https://cert-manager.io/docs/usage/certificate/#issuance-behavior-rotation-of-the-private-key to get more info.
				RotationPolicy: v1.RotationPolicyAlways,
			},
			IssuerRef: cmmeta.ObjectReference{
				Kind: selfSignedCAIssuerKind,
				Name: SelfSignedCAIssuerName,
			},
		},
	}
}

// TiDBComponentsSelfSignedIssuer returns a namespaced issuer which is used to sign the tidb cluster server component certificates
func TiDBComponentsSelfSignedIssuer(ns string) *v1.Issuer {
	return &v1.Issuer{
		ObjectMeta: metav1.ObjectMeta{
			Name:      TiDBComponentsSelfSignedIssuerName,
			Namespace: ns,
		},
		Spec: v1.IssuerSpec{
			IssuerConfig: v1.IssuerConfig{
				CA: &v1.CAIssuer{
					SecretName: tidbComponentSelfSignedCACertSecretName,
				},
			},
		},
	}
}
