package main

import (
	"context"
	"fmt"
	"time"

	"github.com/golang/glog"
	corev1 "k8s.io/api/core/v1"
	rbacv1 "k8s.io/api/rbac/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"

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

func (p *prodvider) kubernetesCreds(username string) (*pb.KubernetesKeys, error) {
	o := fmt.Sprintf("sso:%s", username)
	email := username + "@hackerspace.pl"

	keyRaw, certBytes, err := p.makeKubernetesCertificate(email, o, time.Now().Add(13*time.Hour))
	if err != nil {
		return nil, err
	}

	// Build certificate chain from new cert and intermediate CA.
	chainPEM := append(serializeCert(certBytes), serializeCert(p.intermediateCACert.Raw)...)

	glog.Infof("Generated k8s certificate for %q", username)
	return &pb.KubernetesKeys{
		Cluster: "k0.hswaw.net",
		// APIServerCA
		Ca: serializeCert(p.kubeCACert.Raw),
		// Chain of new cert + intermediate CA
		Cert: chainPEM,
		Key:  serializeKey(keyRaw),
	}, nil
}

func (p *prodvider) kubernetesConnect() error {
	keyRaw, certBytes, err := p.makeKubernetesCertificate("prodvider", "system:masters", time.Now().Add(30*24*time.Hour))
	if err != nil {
		return err
	}

	glog.Infof("Generated k8s certificate for self (system:masters)")

	// Build certificate chain from our cert and intermediate CA.
	chainPEM := append(serializeCert(certBytes), serializeCert(p.intermediateCACert.Raw)...)

	config := &rest.Config{
		Host: flagKubernetesHost,
		TLSClientConfig: rest.TLSClientConfig{
			// Chain to authenticate ourselves (us + intermediate CA).
			CertData: chainPEM,
			KeyData:  serializeKey(keyRaw),
			// APIServer CA for verification.
			CAData: serializeCert(p.kubeCACert.Raw),
		},
	}

	cs, err := kubernetes.NewForConfig(config)
	if err != nil {
		return err
	}

	p.k8s = cs

	return nil
}

// kubernetesSetupUser ensures that for a given SSO username we:
//  - have a personal-<username> namespace
//  - have a sso:<username>:personal rolebinding that binds
//    system:admin-namespace to the user within their personal namespace
//  - have a sso:<username>:global clusterrolebinding that binds
//    system:viewer to the user at cluster level
func (p *prodvider) kubernetesSetupUser(ctx context.Context, username string) error {
	namespace := "personal-" + username
	if err := p.ensureNamespace(ctx, namespace); err != nil {
		return err
	}
	if err := p.ensureRoleBindingPersonal(ctx, namespace, username); err != nil {
		return err
	}
	if err := p.ensureClusterRoleBindingGlobal(ctx, username); err != nil {
		return err
	}

	return nil
}

func (p *prodvider) ensureNamespace(ctx context.Context, name string) error {
	_, err := p.k8s.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{})
	switch {
	case err == nil:
		// Already exists, nothing to do
		return nil
	case errors.IsNotFound(err):
		break
	default:
		// Something went wrong.
		return err
	}
	ns := &corev1.Namespace{
		ObjectMeta: metav1.ObjectMeta{
			Name: name,
		},
	}
	_, err = p.k8s.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{})
	return err
}

func (p *prodvider) ensureRoleBindingPersonal(ctx context.Context, namespace, username string) error {
	name := "sso:" + username + ":personal"
	rb := &rbacv1.RoleBinding{
		ObjectMeta: metav1.ObjectMeta{
			Name:      name,
			Namespace: namespace,
		},
		Subjects: []rbacv1.Subject{
			{
				APIGroup: "rbac.authorization.k8s.io",
				Kind:     "User",
				Name:     username + "@hackerspace.pl",
			},
		},
		RoleRef: rbacv1.RoleRef{
			APIGroup: "rbac.authorization.k8s.io",
			Kind:     "ClusterRole",
			Name:     "system:admin-namespace",
		},
	}

	rbs := p.k8s.RbacV1().RoleBindings(namespace)
	_, err := rbs.Get(ctx, name, metav1.GetOptions{})
	switch {
	case err == nil:
		// Already exists, update.
		_, err = rbs.Update(ctx, rb, metav1.UpdateOptions{})
		return err
	case errors.IsNotFound(err):
		// Create.
		_, err = rbs.Create(ctx, rb, metav1.CreateOptions{})
		return err
	default:
		// Something went wrong.
		return err
	}
}

func (p *prodvider) ensureClusterRoleBindingGlobal(ctx context.Context, username string) error {
	name := "sso:" + username + ":global"
	rb := &rbacv1.ClusterRoleBinding{
		ObjectMeta: metav1.ObjectMeta{
			Name: name,
		},
		Subjects: []rbacv1.Subject{
			{
				APIGroup: "rbac.authorization.k8s.io",
				Kind:     "User",
				Name:     username + "@hackerspace.pl",
			},
		},
		RoleRef: rbacv1.RoleRef{
			APIGroup: "rbac.authorization.k8s.io",
			Kind:     "ClusterRole",
			Name:     "system:viewer",
		},
	}

	crbs := p.k8s.RbacV1().ClusterRoleBindings()
	_, err := crbs.Get(ctx, name, metav1.GetOptions{})
	switch {
	case err == nil:
		// Already exists, update.
		_, err = crbs.Update(ctx, rb, metav1.UpdateOptions{})
		return err
	case errors.IsNotFound(err):
		// Create.
		_, err = crbs.Create(ctx, rb, metav1.CreateOptions{})
		return err
	default:
		// Something went wrong.
		return err
	}
}
