// 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"
)

// 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
	}

	skid, err := calculateSKID(req.PublicKey)
	if err != nil {
		return nil, err
	}

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

	// 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)
}
