// Package revportforward establishes a reverse port-forward from a kubernetes
// pod to localhost.
//
// Setting up a port-forward from a kubernetes pod is simple:
//
//	$ kubectl port-forward mypod 8888:5000
//
// The above will setup a port-forward, i.e. it will listen on port 8888
// locally, forwarding the traffic to 5000 in the pod named "mypod".
//
// What is more involved is setting up a port-forward in the reverse direction,
// which this code does.
//
// Note that for this to work, netcat (nc) must be installed in the pod.
//
// The code works by running netcat (nc) in the pod in listen mode and then
// connects the exec streams to local target address.
//
// This also support having ncrev installed on the pod, a safer version of nc in
// that it checks that there are no other listeners on the given port before
// starting.
package revportforward

import (
	"context"
	"fmt"
	"net"
	"os"

	"go.skia.org/infra/go/skerr"
	v1 "k8s.io/api/core/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/tools/clientcmd/api"
	"k8s.io/client-go/tools/remotecommand"
	"k8s.io/kubectl/pkg/scheme"
)

// ReversePortForward creates reverse port-forwards to pods running in a
// kubernetes cluster.
type ReversePortForward struct {
	config       *rest.Config
	localaddress string
	useNcRev     bool
}

// New returns a new RevPortForward instance.
//
// kubeconfig - The contents of the kubeconfig file.
// podName - The name of the pod found in the cluster pointed to by the kubeconfig file.
// podPort - The port to forward from within the pod.
// localaddress - The address we want the incoming connection to be forwarded
//
//	to, something like "localhost:22"
func New(kubeconfig []byte, localaddress string, useNcRev bool) (*ReversePortForward, error) {
	var kubeConfigGetter clientcmd.KubeconfigGetter = func() (*api.Config, error) {
		return clientcmd.Load(kubeconfig)
	}

	config, err := clientcmd.BuildConfigFromKubeconfigGetter("", kubeConfigGetter)
	if err != nil {
		return nil, skerr.Wrapf(err, "Failed to initialize from kubeconfig: %s", string(kubeconfig))
	}
	return &ReversePortForward{
		config:       config,
		localaddress: localaddress,
		useNcRev:     useNcRev,
	}, nil
}

// Start a reverse port-forward. This function does not return as long as an
// active connection exists.
//
// Note that as connections are made and then closed this function may return,
// so it should be called from within a loop, e.g.:
//
//	for {
//	   if err := rpf.Start(ctx); err != nil {
//			sklog.Error(err)
//		  }
//	}
func (r *ReversePortForward) Start(ctx context.Context, podName string, podPort int) error {
	fmt.Println("Begin")
	// First start a connection to the localaddress.
	var d net.Dialer

	// If the Context is cancelled then this connection should close, which
	// should cause exec.Stream() below to exit, in theory, but it probably
	// won't: https://github.com/kubernetes/client-go/issues/554
	conn, err := d.DialContext(ctx, "tcp", r.localaddress)
	if err != nil {
		return skerr.Wrapf(err, "Failed to connect to localaddress: %s", r.localaddress)
	}

	// Then execute netcat (nc) on the pod.
	clientset, err := kubernetes.NewForConfig(r.config)
	if err != nil {
		panic(err)
	}
	cmd := []string{
		"sh",
		"-c",
		fmt.Sprintf("nc -vv -l -p %d", podPort),
	}
	if r.useNcRev {
		hostname, _ := os.Hostname() // If hostname errs then use the empty string.
		cmd = []string{
			"sh",
			"-c",
			fmt.Sprintf("ncrev --port=:%d --machine=%s", podPort, hostname),
		}
	}
	req := clientset.CoreV1().RESTClient().Post().Resource("pods").Name(podName).Namespace("default").SubResource("exec")
	option := &v1.PodExecOptions{
		Command: cmd,
		Stdin:   true,
		Stdout:  true,
		Stderr:  false,
		TTY:     false,
	}
	req.VersionedParams(
		option,
		scheme.ParameterCodec,
	)
	exec, err := remotecommand.NewSPDYExecutor(r.config, "POST", req.URL())
	if err != nil {
		return skerr.Wrapf(err, "Failed to run netcat on the pod: %q", podName)
	}

	// exec.Stream will not return until the connection is broken.
	err = exec.Stream(remotecommand.StreamOptions{
		Stdin:  conn,
		Stdout: conn,
	})
	if err != nil {
		return skerr.Wrapf(err, "Stream connection failed.")
	}
	return nil
}
