package proto_socket_test

import (
	"context"
	"net"
	"testing"
	"time"

	"nhooyr.io/websocket"

	toki "git.toki-labs.com/toki/proto-socket/go"
	"git.toki-labs.com/toki/proto-socket/go/packets"
)

func TestTLSTcp(t *testing.T) {
	port := freePort(t)
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	serverTLS, clientTLS := generateSelfSignedCert(t)

	server := toki.NewTcpServerTLS("127.0.0.1", port, serverTLS, func(conn net.Conn) *toki.TcpClient {
		return toki.NewTcpClient(conn, 0, 0, testParserMap())
	})
	server.OnClientConnected = func(client *toki.TcpClient) {
		toki.AddRequestListenerTyped[*packets.TestData, *packets.TestData](&client.Communicator, func(req *packets.TestData) (*packets.TestData, error) {
			return &packets.TestData{
				Index:   req.GetIndex() * 2,
				Message: "tls-echo: " + req.GetMessage(),
			}, nil
		})
	}
	if err := server.Start(ctx); err != nil {
		t.Fatal(err)
	}
	defer server.Stop()

	client, err := toki.DialTcpTLS(ctx, "127.0.0.1", port, clientTLS, 0, 0, testParserMap())
	if err != nil {
		t.Fatal(err)
	}
	defer client.Close()

	res, err := toki.SendRequestTyped[*packets.TestData, *packets.TestData](
		&client.Communicator,
		&packets.TestData{Index: 7, Message: "hello tls"},
		2*time.Second,
	)
	if err != nil {
		t.Fatal(err)
	}
	if res.GetIndex() != 14 || res.GetMessage() != "tls-echo: hello tls" {
		t.Fatalf("unexpected response: %v", res)
	}
}

func TestTLSWs(t *testing.T) {
	port := freePort(t)
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	serverTLS, clientTLS := generateSelfSignedCert(t)

	server := toki.NewWsServerTLS("127.0.0.1", port, "/", serverTLS, func(conn *websocket.Conn) *toki.WsClient {
		return toki.NewWsClient(conn, 0, 0, testParserMap())
	})
	server.OnClientConnected = func(client *toki.WsClient) {
		toki.AddRequestListenerTyped[*packets.TestData, *packets.TestData](&client.Communicator, func(req *packets.TestData) (*packets.TestData, error) {
			return &packets.TestData{
				Index:   req.GetIndex() * 2,
				Message: "wss-echo: " + req.GetMessage(),
			}, nil
		})
	}
	if err := server.Start(ctx); err != nil {
		t.Fatal(err)
	}
	defer server.Stop()

	client, err := toki.DialWssWithHeartbeat(ctx, "127.0.0.1", port, "/", clientTLS, 0, 0, testParserMap())
	if err != nil {
		t.Fatal(err)
	}
	defer client.Close()

	res, err := toki.SendRequestTyped[*packets.TestData, *packets.TestData](
		&client.Communicator,
		&packets.TestData{Index: 7, Message: "hello wss"},
		2*time.Second,
	)
	if err != nil {
		t.Fatal(err)
	}
	if res.GetIndex() != 14 || res.GetMessage() != "wss-echo: hello wss" {
		t.Fatalf("unexpected response: %v", res)
	}
}
