// Copyright The Monogon Project Authors.
// SPDX-License-Identifier: Apache-2.0

package pki

import (
	"context"
	"crypto/ed25519"
	"crypto/rand"
	"crypto/x509"
	"fmt"
	"math/big"
	"time"

	clientv3 "go.etcd.io/etcd/client/v3"
)

var (
	// From RFC 5280 Section 4.1.2.5
	UnknownNotAfter = time.Unix(253402300799, 0)
)

// Issuer is an entity that can issue certificates. This interface is
// implemented by SelfSigned, which is an issuer that emits self-signed
// certificates, and any other Certificate that has been created with CA(),
// which makes this Certificate act as a CA and issue (sign) ceritficates.
type Issuer interface {
	// CACertificate returns the DER-encoded x509 certificate of the CA that
	// will sign certificates when Issue is called, or nil if this is
	// self-signing issuer.
	CACertificate(ctx context.Context, kv clientv3.KV) ([]byte, error)
	// Issue will generate a certificate signed by the Issuer. The returned
	// certificate is x509 DER-encoded.
	Issue(ctx context.Context, req *Certificate, kv clientv3.KV) (cert []byte, err error)
}

// issueCertificate is a generic low level certificate-and-key issuance
// function. If ca is null, the certificate will be self-signed. The returned
// certificate is DER-encoded
func issueCertificate(req *Certificate, ca *x509.Certificate, caKey ed25519.PrivateKey) (cert []byte, err error) {
	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 127)
	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
	if err != nil {
		err = fmt.Errorf("failed to generate serial number: %w", err)
		return
	}

	req.Template.SerialNumber = serialNumber
	req.Template.NotBefore = time.Now()
	req.Template.NotAfter = UnknownNotAfter
	req.Template.BasicConstraintsValid = true

	// Set the AuthorityKeyID to the SKID of the signing certificate (or self,
	// if self-signing).
	if ca != nil {
		req.Template.AuthorityKeyId = ca.SubjectKeyId
	} else {
		req.Template.AuthorityKeyId = req.Template.SubjectKeyId
		ca = &req.Template
	}

	return x509.CreateCertificate(rand.Reader, &req.Template, ca, req.PublicKey, caKey)
}

type selfSigned struct{}

var (
	// SelfSigned is an Issuer that generates self-signed certificates.
	SelfSigned = &selfSigned{}
)

// Issue will generate a key and certificate that is self-signed.
func (s *selfSigned) Issue(ctx context.Context, req *Certificate, kv clientv3.KV) (cert []byte, err error) {
	if err := req.ensureKey(ctx, kv); err != nil {
		return nil, err
	}
	if req.PrivateKey == nil {
		return nil, fmt.Errorf("cannot issue self-signed certificate without a private key")
	}
	return issueCertificate(req, nil, req.PrivateKey)
}

// CACertificate returns nil for self-signed issuers.
func (s *selfSigned) CACertificate(ctx context.Context, kv clientv3.KV) ([]byte, error) {
	return nil, nil
}

// Issue will generate a key and certificate that is signed by this
// Certificate, if the Certificate is a CA.
func (c *Certificate) Issue(ctx context.Context, req *Certificate, kv clientv3.KV) (cert []byte, err error) {
	if err := c.ensureKey(ctx, kv); err != nil {
		return nil, fmt.Errorf("could not ensure CA %q key exists: %w", c.Name, err)
	}
	if err := req.ensureKey(ctx, kv); err != nil {
		return nil, fmt.Errorf("could not subject %q key exists: %w", req.Name, err)
	}
	if c.PrivateKey == nil {
		return nil, fmt.Errorf("cannot use certificate without private key as CA")
	}

	caCert, err := c.ensure(ctx, kv)
	if err != nil {
		return nil, fmt.Errorf("could not ensure CA %q certificate exists: %w", c.Name, err)
	}

	ca, err := x509.ParseCertificate(caCert)
	if err != nil {
		return nil, fmt.Errorf("could not parse CA certificate: %w", err)
	}
	// Ensure only one level of CAs exist, and that they are created explicitly.
	req.Template.IsCA = false
	return issueCertificate(req, ca, c.PrivateKey)
}

// CACertificate returns the DER encoded x509 form of this Certificate that
// will be the used to issue child certificates.
func (c *Certificate) CACertificate(ctx context.Context, kv clientv3.KV) ([]byte, error) {
	return c.ensure(ctx, kv)
}
