package pki

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

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

	"source.monogon.dev/metropolis/node/core/consensus/client"
	"source.monogon.dev/metropolis/pkg/event"
	"source.monogon.dev/metropolis/pkg/event/etcd"
)

// crlPath returns the etcd path under which the marshaled X.509 Certificate
// Revocation List is stored.
//
// TODO(q3k): use etcd keyspace API from
func (c *Certificate) crlPath() string {
	return c.Namespace.etcdPath("%s-crl.der", c.Name)
}

// Revoke performs a CRL-based revocation of a given certificate by this CA,
// looking it up by DNS name. The revocation is immediately written to the
// backing etcd store and will be available to consumers through the WatchCRL
// API.
//
// An error is returned if the CRL could not be emitted (eg. due to an etcd
// communication error, a conflicting CRL write) or if the given hostname
// matches no emitted certificate.
//
// Only Managed and External certificates can be revoked.
func (c Certificate) Revoke(ctx context.Context, kv clientv3.KV, hostname string) error {
	crlPath := c.crlPath()
	issuedCerts := c.Namespace.etcdPath("issued/")

	res, err := kv.Txn(ctx).Then(
		clientv3.OpGet(crlPath),
		clientv3.OpGet(issuedCerts, clientv3.WithPrefix())).Commit()
	if err != nil {
		return fmt.Errorf("failed to retrieve certificates and CRL from etcd: %w", err)
	}

	// Parse certs, CRL and CRL revision from state.
	var certs []*x509.Certificate
	var crlRevision int64
	var crl *pkix.CertificateList
	for _, el := range res.Responses {
		for _, kv := range el.GetResponseRange().GetKvs() {
			if string(kv.Key) == crlPath {
				crl, err = x509.ParseCRL(kv.Value)
				if err != nil {
					return fmt.Errorf("could not parse CRL from etcd: %w", err)
				}
				crlRevision = kv.CreateRevision
			} else {
				cert, err := x509.ParseCertificate(kv.Value)
				if err != nil {
					return fmt.Errorf("could not parse certificate %q from etcd: %w", string(kv.Key), err)
				}
				certs = append(certs, cert)
			}
		}
	}
	if crl == nil {
		return fmt.Errorf("could not find CRL in etcd")
	}
	revoked := crl.TBSCertList.RevokedCertificates

	// Find requested hostname in issued certificates.
	var serial *big.Int
	for _, cert := range certs {
		for _, dnsName := range cert.DNSNames {
			if dnsName == hostname {
				serial = cert.SerialNumber
				break
			}
		}
		if serial != nil {
			break
		}
	}
	if serial == nil {
		return fmt.Errorf("could not find requested hostname")
	}

	// Check if certificate has already been revoked.
	for _, revokedCert := range revoked {
		if revokedCert.SerialNumber.Cmp(serial) == 0 {
			return nil // Already revoked
		}
	}

	// Otherwise, revoke and save new CRL.
	revoked = append(revoked, pkix.RevokedCertificate{
		SerialNumber:   serial,
		RevocationTime: time.Now(),
	})

	crlRaw, err := c.makeCRL(ctx, kv, revoked)
	if err != nil {
		return fmt.Errorf("when generating new CRL for revocation: %w", err)
	}

	res, err = kv.Txn(ctx).If(
		clientv3.Compare(clientv3.CreateRevision(crlPath), "=", crlRevision),
	).Then(
		clientv3.OpPut(crlPath, string(crlRaw)),
	).Commit()
	if err != nil {
		return fmt.Errorf("when saving new CRL: %w", err)
	}
	if !res.Succeeded {
		return fmt.Errorf("CRL save transaction failed, retry possible")
	}

	return nil
}

// makeCRL returns a valid CRL for a given list of certificates to be revoked.
// The given etcd client is used to ensure this CA certificate exists in etcd,
// but is not used to write any CRL to etcd.
func (c *Certificate) makeCRL(ctx context.Context, kv clientv3.KV, revoked []pkix.RevokedCertificate) ([]byte, error) {
	if c.Mode != CertificateManaged {
		return nil, fmt.Errorf("only managed certificates can issue CRLs")
	}
	certBytes, err := c.ensure(ctx, kv)
	if err != nil {
		return nil, fmt.Errorf("when ensuring certificate: %w", err)
	}
	cert, err := x509.ParseCertificate(certBytes)
	if err != nil {
		return nil, fmt.Errorf("when parsing issuing certificate: %w", err)
	}
	crl, err := cert.CreateCRL(rand.Reader, c.PrivateKey, revoked, time.Now(), UnknownNotAfter)
	if err != nil {
		return nil, fmt.Errorf("failed to generate CRL: %w", err)
	}
	return crl, nil
}

// WatchCRL returns and Event Value compatible CRLWatcher which can be used to
// retrieve and watch for the newest CRL available from this CA certificate.
func (c *Certificate) WatchCRL(cl client.Namespaced) CRLWatcher {
	value := etcd.NewValue(cl, c.crlPath(), func(_, data []byte) (interface{}, error) {
		crl, err := x509.ParseCRL(data)
		if err != nil {
			return nil, fmt.Errorf("could not parse CRL from etcd: %w", err)
		}
		return &CRL{
			Raw:  data,
			List: crl,
		}, nil
	})
	return CRLWatcher{value.Watch()}
}

// CRLWatcher is a Event Value compatible Watcher which will be updated any time
// a given CA certificate's CRL gets updated.
type CRLWatcher struct {
	event.Watcher
}

type CRL struct {
	Raw  []byte
	List *pkix.CertificateList
}

// Retrieve the newest available CRL from etcd, blocking until one is available
// or updated.
//
// The first call will block until a CRL is available, which happens the first
// time a given CA certificate is stored in etcd (eg. through an Ensure call).
func (c *CRLWatcher) Get(ctx context.Context, opts ...event.GetOption) (*CRL, error) {
	v, err := c.Watcher.Get(ctx, opts...)
	if err != nil {
		return nil, err
	}
	return v.(*CRL), nil
}
