package ssh

import (
	"fmt"
	"net"
	"strconv"
	"strings"

	"github.com/hashicorp/packer/communicator/ssh"
)

// ParseTunnelArgument parses an SSH tunneling argument compatible with the openssh client form.
// Valid formats:
// `port:host:hostport`
// NYI `[bind_address:]port:host:hostport`
func ParseTunnelArgument(forward string, direction ssh.TunnelDirection) (ssh.TunnelSpec, error) {
	parts := strings.SplitN(forward, ":", 2)
	if len(parts) != 2 {
		return ssh.TunnelSpec{}, fmt.Errorf("Error parsing tunnel '%s': %v", forward, parts)
	}
	listeningPort, forwardingAddr := parts[0], parts[1]

	_, sPort, err := net.SplitHostPort(forwardingAddr)
	if err != nil {
		return ssh.TunnelSpec{}, fmt.Errorf("Error parsing forwarding, must be a tcp address: %s", err)
	}
	_, err = strconv.Atoi(sPort)
	if err != nil {
		return ssh.TunnelSpec{}, fmt.Errorf("Error parsing forwarding port, must be a valid port: %s", err)
	}
	_, err = strconv.Atoi(listeningPort)
	if err != nil {
		return ssh.TunnelSpec{}, fmt.Errorf("Error parsing listening port, must be a valid port: %s", err)
	}

	return ssh.TunnelSpec{
		Direction:   direction,
		ForwardAddr: forwardingAddr,
		ForwardType: "tcp",
		ListenAddr:  fmt.Sprintf("localhost:%s", listeningPort),
		ListenType:  "tcp",
	}, nil
	// So we parsed all that, and are just going to ignore it now. We would
	// have used the information to set the type here.
}
