package keypair

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/base64"
	"io"
	"os"
	"strings"
)

// KeyPair represents a pair of certificate and key.
type KeyPair struct {
	CertPath     string
	KeyPath      string
	CACertPath   string
	CACertBase64 string
	TLSConfig    *tls.Config
}

// None represents non-TLS.
var None KeyPair

// Server is a KeyPair for TLS server.
// These files should be generated by Makefile before test.
var Server = KeyPair{
	CertPath:     "keypair/testdata/server.crt",
	KeyPath:      "keypair/testdata/server.key",
	CACertPath:   "keypair/testdata/ca.crt",
	CACertBase64: readAsBase64("keypair/testdata/ca.crt"),
	TLSConfig:    newTLSConfig("keypair/testdata/ca.crt"),
}

func readAsBase64(name string) string {
	f, err := os.Open(name)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	var s strings.Builder
	e := base64.NewEncoder(base64.StdEncoding, &s)
	if _, err := io.Copy(e, f); err != nil {
		panic(err)
	}
	if err := e.Close(); err != nil {
		panic(err)
	}
	return s.String()
}

func newTLSConfig(name string) *tls.Config {
	b, err := os.ReadFile(name)
	if err != nil {
		panic(err)
	}
	p := x509.NewCertPool()
	if !p.AppendCertsFromPEM(b) {
		panic("could not append the CA cert")
	}
	return &tls.Config{RootCAs: p}
}
