package socksproxy

import (
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"net"
)

// readMethods implements RFC1928 3. “Procedure for TCP-based clients”,
// paragraph 3. It receives a 'version identifier/method selection message' from
// r and returns the methods supported by the client.
func readMethods(r io.Reader) ([]method, error) {
	var ver uint8
	if err := binary.Read(r, binary.BigEndian, &ver); err != nil {
		return nil, fmt.Errorf("when reading ver: %w", err)
	}
	if ver != 5 {
		return nil, fmt.Errorf("unimplemented version %d", ver)
	}
	var nmethods uint8
	if err := binary.Read(r, binary.BigEndian, &nmethods); err != nil {
		return nil, fmt.Errorf("when reading nmethods: %w", err)
	}
	methodBytes := make([]byte, nmethods)
	if _, err := io.ReadFull(r, methodBytes); err != nil {
		return nil, fmt.Errorf("while reading methods: %w", err)
	}
	methods := make([]method, nmethods)
	for i, m := range methodBytes {
		methods[i] = method(m)
	}
	return methods, nil
}

// writeMethod implements RFC1928 3. “Procedure for TCP-based clients”,
// paragraph 5. It sends a selected method to w.
func writeMethod(w io.Writer, m method) error {
	if err := binary.Write(w, binary.BigEndian, uint8(5)); err != nil {
		return fmt.Errorf("while writing version: %w", err)
	}
	if err := binary.Write(w, binary.BigEndian, uint8(m)); err != nil {
		return fmt.Errorf("while writing method: %w", err)
	}
	return nil
}

// method is an RFC1928 authentication method.
type method uint8

const (
	methodNoAuthenticationRequired method = 0
	methodNoAcceptableMethods      method = 0xff
)

// negotiateMethod implements the entire flow RFC1928 3. “Procedure for
// TCP-based clients” by negotiating for the 'NO AUTHENTICATION REQUIRED'
// authentication method, and failing otherwise.
func negotiateMethod(rw io.ReadWriter) error {
	methods, err := readMethods(rw)
	if err != nil {
		return fmt.Errorf("could not read methods: %w", err)
	}

	found := false
	for _, m := range methods {
		if m == methodNoAuthenticationRequired {
			found = true
			break
		}
	}
	if !found {
		// Discard error, as this connection is failed anyway.
		writeMethod(rw, methodNoAcceptableMethods)
		return fmt.Errorf("no acceptable methods found")
	}
	if err := writeMethod(rw, methodNoAuthenticationRequired); err != nil {
		return fmt.Errorf("could not respond with method: %w", err)
	}
	return nil
}

var (
	// errNotConnect is returned by readRequest when the request contained some
	// other request than CONNECT.
	errNotConnect = errors.New("not CONNECT")
	// errUnsupportedAddressType is returned by readRequest when the request
	// contained some unsupported address type (not IPv4 or IPv6).
	errUnsupportedAddressType = errors.New("unsupported address type")
)

// readRequest implements RFC1928 4. “Requests” by reading a SOCKS request from
// r and ensuring it's an IPv4/IPv6 CONNECT request. The parsed address/port
// pair is then returned.
func readRequest(r io.Reader) (*connectRequest, error) {
	header := struct {
		Ver  uint8
		Cmd  uint8
		Rsv  uint8
		Atyp uint8
	}{}
	if err := binary.Read(r, binary.BigEndian, &header); err != nil {
		return nil, fmt.Errorf("when reading request header: %w", err)
	}

	if header.Ver != 5 {
		return nil, fmt.Errorf("invalid version %d", header.Ver)
	}
	if header.Cmd != 1 {
		return nil, errNotConnect
	}

	var addrBytes []byte
	switch header.Atyp {
	case 1:
		addrBytes = make([]byte, 4)
	case 4:
		addrBytes = make([]byte, 16)
	default:
		return nil, errUnsupportedAddressType
	}
	if _, err := io.ReadFull(r, addrBytes); err != nil {
		return nil, fmt.Errorf("when reading address: %w", err)
	}

	var port uint16
	if err := binary.Read(r, binary.BigEndian, &port); err != nil {
		return nil, fmt.Errorf("when reading port: %w", err)
	}

	return &connectRequest{
		address: addrBytes,
		port:    port,
	}, nil
}

type connectRequest struct {
	address net.IP
	port    uint16
}

// Reply is an RFC1928 6. “Replies” reply field value. It's returned to the
// client by internal socksproxy code or a Handler to signal a success or error
// condition within an RFC1928 reply.
type Reply uint8

const (
	ReplySucceeded               Reply = 0
	ReplyGeneralFailure          Reply = 1
	ReplyConnectionNotAllowed    Reply = 2
	ReplyNetworkUnreachable      Reply = 3
	ReplyHostUnreachable         Reply = 4
	ReplyConnectionRefused       Reply = 5
	ReplyTTLExpired              Reply = 6
	ReplyCommandNotSupported     Reply = 7
	ReplyAddressTypeNotSupported Reply = 8
)

// writeReply implements RFC1928 6. “Replies” by sending a given Reply, bind
// address and bind port to w. An error is returned if the given bind address is
// invaild, or if a communication error occurred.
func writeReply(w io.Writer, r Reply, bindAddr net.IP, bindPort uint16) error {
	var atyp uint8
	switch len(bindAddr) {
	case 4:
		atyp = 1
	case 16:
		atyp = 4
	default:
		return fmt.Errorf("unsupported bind address type")
	}

	header := struct {
		Ver   uint8
		Reply uint8
		Rsv   uint8
		Atyp  uint8
	}{
		Ver:   5,
		Reply: uint8(r),
		Rsv:   0,
		Atyp:  atyp,
	}
	if err := binary.Write(w, binary.BigEndian, &header); err != nil {
		return fmt.Errorf("when writing reply header: %w", err)
	}
	if _, err := w.Write(bindAddr); err != nil {
		return fmt.Errorf("when writing reply bind address: %w", err)
	}
	if err := binary.Write(w, binary.BigEndian, bindPort); err != nil {
		return fmt.Errorf("when writing reply bind port: %w", err)
	}
	return nil
}
