package k8s

import (
	"context"

	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/tools/clientcmd/api"

	"go.skia.org/infra/go/kube/clusterconfig"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
)

// Client provides an interface for interacting with a Kubernetes cluster. It is
// a thin wrapper around the Kubernetes API which allows for mocking requests.
type Client interface {
	// ListNamespaces retrieves all namespaces in the cluster.
	ListNamespaces(ctx context.Context, opts metav1.ListOptions) ([]corev1.Namespace, error)

	// ListPods retrieves all pods in the namespace.
	ListPods(ctx context.Context, namespace string, opts metav1.ListOptions) ([]corev1.Pod, error)

	// DeletePod deletes a pod.
	DeletePod(ctx context.Context, namespace, name string, opts metav1.DeleteOptions) error

	// ListStatefulSets retrieves all stateful sets in the namespace.
	ListStatefulSets(ctx context.Context, namespace string, opts metav1.ListOptions) ([]appsv1.StatefulSet, error)

	// GetStatefulSet retrieves a single StatefulSet.
	GetStatefulSet(ctx context.Context, namespace, name string, opts metav1.GetOptions) (*appsv1.StatefulSet, error)

	// GetEvents retrieves events for the given namespace.
	GetEvents(ctx context.Context, namespace string) ([]corev1.Event, error)
}

// ClientImpl implements Client.
type ClientImpl struct {
	c *kubernetes.Clientset
}

// NewClient returns a ClientImpl instance.
// TODO(borenet): Handle more of the setup here.
func NewClient(ctx context.Context, clientset *kubernetes.Clientset) (*ClientImpl, error) {
	return &ClientImpl{
		c: clientset,
	}, nil
}

// GetNamespaces implements Client.
func (c *ClientImpl) ListNamespaces(ctx context.Context, opts metav1.ListOptions) ([]corev1.Namespace, error) {
	result, err := c.c.CoreV1().Namespaces().List(ctx, opts)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return result.Items, nil
}

// GetPods implements Client.
func (c *ClientImpl) ListPods(ctx context.Context, namespace string, opts metav1.ListOptions) ([]corev1.Pod, error) {
	result, err := c.c.CoreV1().Pods(namespace).List(ctx, opts)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return result.Items, nil
}

// DeletePod implements Client.
func (c *ClientImpl) DeletePod(ctx context.Context, namespace, name string, opts metav1.DeleteOptions) error {
	return skerr.Wrap(c.c.CoreV1().Pods(namespace).Delete(ctx, name, opts))
}

// ListStatefulSets implements Client.
func (c *ClientImpl) ListStatefulSets(ctx context.Context, namespace string, opts metav1.ListOptions) ([]appsv1.StatefulSet, error) {
	result, err := c.c.AppsV1().StatefulSets(namespace).List(ctx, opts)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return result.Items, nil
}

// GetStatefulSet implements Client.
func (c *ClientImpl) GetStatefulSet(ctx context.Context, namespace, name string, opts metav1.GetOptions) (*appsv1.StatefulSet, error) {
	result, err := c.c.AppsV1().StatefulSets(namespace).Get(ctx, name, metav1.GetOptions{})
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return result, nil
}

// GetEvents implements Client.
func (c *ClientImpl) GetEvents(ctx context.Context, namespace string) ([]corev1.Event, error) {
	resp, err := c.c.CoreV1().Events(namespace).List(ctx, metav1.ListOptions{})
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return resp.Items, nil
}

// Assert that ClientImpl implements Client.
var _ Client = &ClientImpl{}

// NewInClusterClient creates a Client which can be used to interact with the
// cluster in which this service is running.
func NewInClusterClient(ctx context.Context) (*ClientImpl, error) {
	config, err := rest.InClusterConfig()
	if err != nil {
		return nil, skerr.Wrapf(err, "failed to get in-cluster config")
	}
	sklog.Infof("Auth username: %s", config.Username)
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, skerr.Wrapf(err, "failed to get in-cluster clientset")
	}
	return NewClient(ctx, clientset)
}

// NewLocalClient uses the local kubeconfig file, the clusters config.json file,
// and a cluster name to create a Client which can be used to interact with that
// cluster.
// TODO(borenet): This requires that the user has previously created credentials
// for the requested cluster.
func NewLocalClient(ctx context.Context, kubeConfigFile, clusterConfigFile, cluster string) (*ClientImpl, error) {
	clusterConfig, err := clusterconfig.New(clusterConfigFile)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	clusterInfo, ok := clusterConfig.Clusters[cluster]
	if !ok {
		return nil, skerr.Fmt("unknown cluster %q", cluster)
	}
	cfg, err := clientcmd.LoadFromFile(kubeConfigFile)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	cfg.CurrentContext = clusterInfo.ContextName
	clusterCfg, ok := cfg.Clusters[clusterInfo.ContextName]
	if !ok {
		return nil, skerr.Fmt("no cluster config for %q", clusterInfo.ContextName)
	}
	restCfg, err := clientcmd.BuildConfigFromKubeconfigGetter(clusterCfg.Server, func() (*api.Config, error) {
		return cfg, nil
	})
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	clientset, err := kubernetes.NewForConfig(restCfg)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return NewClient(ctx, clientset)
}
