package component

import (
	"crypto/ed25519"
	"crypto/rand"
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"math/big"
	"os"
	"time"

	"k8s.io/klog/v2"

	"source.monogon.dev/metropolis/pkg/pki"
)

// GetDevCerts returns paths to this component's development certificate, key
// and CA, or panics if unavailable.
func (c *ComponentConfig) GetDevCerts() (certPath, keyPath, caPath string) {
	klog.Infof("Using developer certificates at %s", c.DevCertsPath)

	caPath = c.ensureDevCA()
	certPath, keyPath = c.ensureDevComponent()
	return
}

// ensureDevComponent ensures that a development certificate/key exists for this
// component and returns paths to them. This data is either read from disk if it
// already exists, or is generated when this function is called. If any problem
// occurs, the code panics.
func (c *ComponentConfig) ensureDevComponent() (certPath, keyPath string) {
	caKeyPath := c.DevCertsPath + "/ca.key"
	caCertPath := c.DevCertsPath + "/ca.cert"

	// Load CA. By convention, we are always called after ensureDevCA.
	ca, err := tls.LoadX509KeyPair(caCertPath, caKeyPath)
	if err != nil {
		klog.Exitf("Could not load Dev CA: %v", err)
	}
	caCert, err := x509.ParseCertificate(ca.Certificate[0])
	if err != nil {
		klog.Exitf("Could not parse Dev CA: %v", err)
	}

	// Check if we have keys already.
	keyPath = c.DevCertsPath + fmt.Sprintf("/%s.key", c.ComponentName)
	certPath = c.DevCertsPath + fmt.Sprintf("/%s.crt", c.ComponentName)
	noKey := false
	if _, err := os.Stat(keyPath); os.IsNotExist(err) {
		noKey = true
	}
	noCert := false
	if _, err := os.Stat(certPath); os.IsNotExist(err) {
		noCert = true
	}

	if noKey || noCert {
		klog.Infof("Generating developer %s certificate...", c.ComponentName)
	} else {
		return
	}

	// Generate key/certificate.
	cert := pki.Server([]string{
		fmt.Sprintf("%s.local", c.ComponentName),
	}, nil)

	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 127)
	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
	if err != nil {
		klog.Exitf("Failed to generate %s serial number: %v", c.ComponentName, err)
	}
	cert.ExtKeyUsage = append(cert.ExtKeyUsage, x509.ExtKeyUsageClientAuth)
	cert.SerialNumber = serialNumber
	cert.NotBefore = time.Now()
	cert.NotAfter = pki.UnknownNotAfter
	cert.BasicConstraintsValid = true

	pub, priv, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		klog.Exitf("Failed to generate %s key: %v", c.ComponentName, err)
	}
	certBytes, err := x509.CreateCertificate(rand.Reader, &cert, caCert, pub, ca.PrivateKey)
	if err != nil {
		klog.Exitf("Failed to generate %s certificate: %v", c.ComponentName, err)
	}

	// And marshal them to disk.
	privPKCS, err := x509.MarshalPKCS8PrivateKey(priv)
	if err != nil {
		klog.Exitf("Failed to marshal %s private key: %v", c.ComponentName, err)
	}
	err = os.WriteFile(keyPath, pem.EncodeToMemory(&pem.Block{
		Type:  "PRIVATE KEY",
		Bytes: privPKCS,
	}), 0600)
	if err != nil {
		klog.Exitf("Failed to write %s private key: %v", c.ComponentName, err)
	}
	err = os.WriteFile(certPath, pem.EncodeToMemory(&pem.Block{
		Type:  "CERTIFICATE",
		Bytes: certBytes,
	}), 0644)
	if err != nil {
		klog.Exitf("Failed to write %s certificate: %v", c.ComponentName, err)
	}

	return
}

// ensureDevCA ensures that a development CA certificate/key exists and returns
// paths to them. This data is either read from disk if it already exists, or is
// generated when this function is called. If any problem occurs, the code
// panics.
func (c *ComponentConfig) ensureDevCA() (caCertPath string) {
	caKeyPath := c.DevCertsPath + "/ca.key"
	caCertPath = c.DevCertsPath + "/ca.cert"

	if err := os.MkdirAll(c.DevCertsPath, 0700); err != nil {
		klog.Exitf("Failed to make developer certificate directory: %v", err)
	}

	// Check if we already have a key/certificate.
	noKey := false
	if _, err := os.Stat(caKeyPath); os.IsNotExist(err) {
		noKey = true
	}
	noCert := false
	if _, err := os.Stat(caCertPath); os.IsNotExist(err) {
		noCert = true
	}

	if noKey || noCert {
		klog.Infof("Generating developer CA certificate...")
	} else {
		return
	}
	hostname, err := os.Hostname()
	if err != nil {
		hostname = "unknown"
	}

	// No key/certificate, generate them.
	ca := pki.CA(fmt.Sprintf("monogon dev certs CA (%s)", hostname))

	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 127)
	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
	if err != nil {
		klog.Exitf("Failed to generate CA serial number: %v", err)
	}
	ca.SerialNumber = serialNumber
	ca.NotBefore = time.Now()
	ca.NotAfter = pki.UnknownNotAfter
	ca.BasicConstraintsValid = true

	caPub, caPriv, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		klog.Exitf("Failed to generate CA key: %v", err)
	}
	caBytes, err := x509.CreateCertificate(rand.Reader, &ca, &ca, caPub, caPriv)
	if err != nil {
		klog.Exitf("Failed to generate CA certificate: %v", err)
	}

	// And marshal them to disk.
	caPrivPKCS, err := x509.MarshalPKCS8PrivateKey(caPriv)
	if err != nil {
		klog.Exitf("Failed to marshal %s private key: %v", c.ComponentName, err)
	}
	err = os.WriteFile(caKeyPath, pem.EncodeToMemory(&pem.Block{
		Type:  "PRIVATE KEY",
		Bytes: caPrivPKCS,
	}), 0600)
	if err != nil {
		klog.Exitf("Failed to write CA private key: %v", err)
	}
	err = os.WriteFile(caCertPath, pem.EncodeToMemory(&pem.Block{
		Type:  "CERTIFICATE",
		Bytes: caBytes,
	}), 0644)
	if err != nil {
		klog.Exitf("Failed to write CA certificate: %v", err)
	}

	return
}
