package main

import (
	"crypto/ed25519"
	"crypto/x509"
	"encoding/pem"
	"flag"
	"fmt"
	"math/rand"
	"net"
	"os"
	"time"

	"github.com/golang/glog"
	"google.golang.org/grpc"
	"k8s.io/client-go/kubernetes"

	pb "code.hackerspace.pl/hscloud/cluster/prodvider/proto"
)

var (
	flagLDAPServer          string
	flagLDAPBindDN          string
	flagLDAPGroupSearchBase string
	flagListenAddress       string
	flagKubernetesHost      string

	flagCACertificatePath     string
	flagCAKeyPath             string
	flagKubeCACertificatePath string

	flagProdviderCN string
)

func init() {
	flag.Set("logtostderr", "true")
}

type prodvider struct {
	k8s *kubernetes.Clientset
	srv *grpc.Server

	intermediateCAKey  ed25519.PrivateKey
	intermediateCACert *x509.Certificate
	kubeCACert         *x509.Certificate
}

func loadCert(path string) (*x509.Certificate, error) {
	b, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}

	block, _ := pem.Decode(b)
	if block == nil {
		return nil, fmt.Errorf("no PEM block found")
	}
	if block.Type != "CERTIFICATE" {
		return nil, fmt.Errorf("unexpected PEM block: %q", block.Type)
	}
	return x509.ParseCertificate(block.Bytes)
}

func loadKey(path string) (ed25519.PrivateKey, error) {
	bytes, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}
	block, _ := pem.Decode(bytes)
	if block == nil {
		return nil, fmt.Errorf("no PEM block found")
	}
	if block.Type != "PRIVATE KEY" {
		return nil, fmt.Errorf("unexpected PEM block: %q", block.Type)
	}
	key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	if k, ok := key.(ed25519.PrivateKey); ok {
		return k, nil
	}
	return nil, fmt.Errorf("not an ED25519 key")
}

func newProdvider() *prodvider {
	kubeCACert, err := loadCert(flagKubeCACertificatePath)
	if err != nil {
		glog.Exitf("Loading kube CA certificate failed: %v", err)
	}
	intermediateCACert, err := loadCert(flagCACertificatePath)
	if err != nil {
		glog.Exitf("Loading intermediate CAcertificate failed: %v", err)
	}
	intermediateCAKey, err := loadKey(flagCAKeyPath)
	return &prodvider{
		intermediateCAKey:  intermediateCAKey,
		intermediateCACert: intermediateCACert,
		kubeCACert:         kubeCACert,
	}
}

// Timebomb restarts the prodvider after a deadline, usually 7 days +/- 4 days.
// This is to ensure we serve with up-to-date certificates and that the service
// can still come up after restart.
func timebomb(srv *grpc.Server) {
	deadline := time.Now()
	deadline = deadline.Add(3 * 24 * time.Hour)
	rand.Seed(time.Now().UnixNano())
	jitter := rand.Intn(8 * 24 * 60 * 60)
	deadline = deadline.Add(time.Duration(jitter) * time.Second)

	glog.Infof("Timebomb deadline set to %v", deadline)

	t := time.NewTicker(time.Minute)
	for {
		<-t.C
		if time.Now().After(deadline) {
			break
		}
	}

	// Start killing connections, and wait one minute...
	go srv.GracefulStop()
	<-t.C
	glog.Infof("Timebomb deadline exceeded, restarting.")
	os.Exit(0)
}

func main() {
	flag.StringVar(&flagLDAPServer, "ldap_server", "ldap.hackerspace.pl:636", "Address of LDAP server")
	flag.StringVar(&flagLDAPBindDN, "ldap_bind_dn", "uid=%s,ou=People,dc=hackerspace,dc=pl", "LDAP Bind DN")
	flag.StringVar(&flagLDAPGroupSearchBase, "ldap_group_search_base_dn", "ou=Group,dc=hackerspace,dc=pl", "LDAP Group Search Base DN")
	flag.StringVar(&flagListenAddress, "listen_address", "127.0.0.1:8080", "gRPC listen address")
	flag.StringVar(&flagKubernetesHost, "kubernetes_host", "k0.hswaw.net:4001", "Kubernetes API host")

	flag.StringVar(&flagCACertificatePath, "ca_certificate_path", "", "CA certificate path (for signer)")
	flag.StringVar(&flagCAKeyPath, "ca_key_path", "", "CA key path (for signer)")
	flag.StringVar(&flagKubeCACertificatePath, "kube_ca_certificate_path", "", "CA certificate path (for checking kube apiserver)")

	flag.StringVar(&flagProdviderCN, "prodvider_cn", "prodvider.hswaw.net", "CN of certificate that prodvider will use")
	flag.Parse()

	if flagCACertificatePath == "" || flagCAKeyPath == "" {
		glog.Exitf("CA certificate and key must be provided")
	}

	p := newProdvider()
	err := p.kubernetesConnect()
	if err != nil {
		glog.Exitf("Could not connect to kubernetes: %v", err)
	}
	creds := p.selfCreds()

	// Start serving gRPC
	grpcLis, err := net.Listen("tcp", flagListenAddress)
	if err != nil {
		glog.Exitf("Could not listen for gRPC on %q: %v", flagListenAddress, err)
	}

	glog.Infof("Starting gRPC on %q...", flagListenAddress)
	grpcSrv := grpc.NewServer(creds)

	pb.RegisterProdviderServer(grpcSrv, p)

	go timebomb(grpcSrv)

	err = grpcSrv.Serve(grpcLis)
	if err != nil {
		glog.Exitf("Could not serve gRPC: %v", err)
	}
}
