package kubernetes_client

import (
	"bytes"
	"context"
	"fmt"
	"kube-forge/internal/config"
	"net/http"
	"strings"
	"time"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/remotecommand"
)

func ExecuteCommandInPodContainer(commandArray []string, namespace string, podName string, container string) (string, error) {
	clientset, err := kubernetes.NewForConfig(config.GetKubernetesConfig())
	if err != nil {
		panic(err.Error())
	}

	execRequest := clientset.CoreV1().RESTClient().Post().
		Resource("pods").
		Name(podName).
		Namespace(namespace).
		SubResource("exec").
		Param("container", container).
		Param("stderr", "true").
		Param("stdout", "true")
	for _, com := range commandArray {
		execRequest = execRequest.Param("command", com)
	}

	stderr := bytes.NewBufferString("")
	stdout := bytes.NewBufferString("")

	streamOptions := remotecommand.StreamOptions{
		Stdout: stdout,
		Stderr: stderr,
		Tty:    false,
	}

	exec, err := remotecommand.NewSPDYExecutor(config.GetKubernetesConfig(), http.MethodPost, execRequest.URL())
	if err != nil {
		fmt.Println(err.Error())
	}

	err = exec.StreamWithContext(context.Background(), streamOptions)
	if err != nil {
		if stderr.Len() == 0 {
			panic(err)
		}
		outputErr := stderr.String()
		return outputErr, err
	}
	output := stdout.String()
	return output, nil
}

func GetPodByName(podName string, podNamespace string) (*corev1.Pod, error) {
	clientset, err := kubernetes.NewForConfig(config.GetKubernetesConfig())
	if err != nil {
		panic(err.Error())
	}
	for i := 15; i > 0; i-- {
		time.Sleep(time.Second * 1)

		pod, err := clientset.CoreV1().
			Pods(podNamespace).
			Get(context.Background(), podName, metav1.GetOptions{})
		if err != nil || pod.Status.Phase != "Running" {
			continue
		}
		return pod, nil
	}
	return nil, err
}

func GetEnvVariableFromPodContainer(envVarName string, podNamespace string, podName string, containerName string) (string, error) {
	commandArray := []string{"env"}
	output, err := ExecuteCommandInPodContainer(
		commandArray, podNamespace, podName, containerName,
	)
	if err != nil {
		return output, err
	}
	lines := strings.Split(output, "\n")

	for _, line := range lines {
		if strings.HasPrefix(line, envVarName+"=") {
			parts := strings.Split(line, "=")
			if len(parts) == 2 {
				value := parts[1]
				return value, nil
			}
		}
	}
	return "", NoSuchVarInPod
}
