package main

import (
	"fmt"
	"log"
	"net"
	"os"
	"strings"

	"ben.soroos.net/tsnet-proxy/netforward"
	"tailscale.com/tsnet"
)

var hostname = os.Args[1]


type Dialer struct{
	proto string;
	addr string;
}

type Forward struct{
	proto string;
	port string;
	dst string;
}

func (dialer Dialer) Dial() (net.Conn, error) {
	return net.Dial(dialer.proto, dialer.addr)
}

func (forward Forward) Run(server *tsnet.Server, finish chan error) {
	ln, err := server.Listen(forward.proto, fmt.Sprint(":", forward.port))
	defer ln.Close()
	if err != nil {
		finish <- err
	}
	err = netforward.Forward(Dialer { proto: forward.proto, addr: forward.dst }, ln)
	if err != nil {
		finish <- err
	}
}

func main() {
	if !(hostname != "") {
		fmt.Println("Usage: tsnet-proxy HOSTNAME FORWARDS...")
		os.Exit(1)
	}

	dir, valid := os.LookupEnv("STATE_DIRECTORY")
	if !valid {
		log.Fatal("RUNTIME_DIRECTORY must be set")
	}
	s := &tsnet.Server{
		Hostname: hostname,
		Dir: dir,
	}
	defer s.Close()

	err_chan := make(chan error)
	for _, arg := range os.Args[2:] {
		args := strings.SplitN(arg, ":", 3)
		proto, port, dst := args[0], args[1], args[2]
		go func() {
			Forward { proto, port, dst }.Run(s, err_chan);
		}();
	}
	err := <- err_chan 
	log.Fatal(err)
}
