package cert

import (
	"time"

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

const (
	awsIssuerKind  = "AWSPCAClusterIssuer"
	awsIssuerGroup = "awspca.cert-manager.io"

	PCAIssuerName = "cluster-issuer" // PCA issuer, keep it as cluster-issuer for backward compatibility

	tidbServerCertificateDuration     = 10 * 365 * 24 * time.Hour // 10 years
	tiProxyServerCertificateDuration  = 5 * 365 * 24 * time.Hour  // 5 years
	selfSignedComponentCACertDuration = 15 * 365 * 24 * time.Hour // 15 years
	selfSignedComponentCertDuration   = 13 * 30 * 24 * time.Hour  // 13 months
	renewBefore                       = 30 * 24 * time.Hour       // 30 days
	certOrganization                  = "PingCAP"

	selfSignedIssuerGroup = "cert-manager.io"

	tidbComponentsSelfSignedCACertName = "tidb-components-self-signed-ca-cert" // Self Signed Cluster CA cert for TiDB inter-components

	tidbComponentsSelfSignedIssuerKind = v1.IssuerKind
	// TiDBComponentsSelfSignedIssuerName Security team recommend to use self-signed CA cert per cluster to maximize the isolation of cluster.
	// Therefore, we create namespaced, per-cluster self-signed issuer for tidb component certs.
	tidbComponentsSelfSignedIssuerName = "tidb-components-self-signed-issuer" // Self Signed Issuer for TiDB components

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

// 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: selfSignedComponentCACertDuration},
			RenewBefore: &metav1.Duration{Duration: 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 sharedPool 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,
				},
			},
		},
	}
}
