package comms

import (
	"context"
	"git.wamblee.org/converge/pkg/testsupport"
	"github.com/stretchr/testify/suite"
	"net"
	"net/http"
	"testing"
	"time"
)

type GOBChannelTestSuite struct {
	suite.Suite

	ctx         context.Context
	cancelFunc  context.CancelFunc
	pprofServer *http.Server

	agentConnection  net.Conn
	serverConnection net.Conn

	agentGOB  GOBChannel
	serverGOB GOBChannel
}

func (s *GOBChannelTestSuite) SetupSuite() {
	s.pprofServer = testsupport.StartPprof("")
}

func (s *GOBChannelTestSuite) TearDownSuite() {
	testsupport.StopPprof(s.ctx, s.pprofServer)
}

func (s *GOBChannelTestSuite) SetupTest() {
	ctx, cancelFunc := testsupport.CreateTestContext(context.Background(), 10*time.Second)
	s.ctx = ctx
	s.cancelFunc = cancelFunc
	agentConnection, serverConnection := net.Pipe()
	deadline := time.Now().Add(10 * time.Second)
	agentConnection.SetDeadline(deadline)
	serverConnection.SetDeadline(deadline)
	s.agentConnection = agentConnection
	s.serverConnection = serverConnection
	s.agentGOB = NewGOBChannel(s.agentConnection)
	s.serverGOB = NewGOBChannel(s.serverConnection)
}

func (s *GOBChannelTestSuite) TearDownTest() {
}

func TestNewGOBChannelSuite(t *testing.T) {
	suite.Run(t, &GOBChannelTestSuite{})
}

func (s *GOBChannelTestSuite) Test_SendConcreteObject() {
	protocol := ProtocolVersion{
		Version: 10,
	}
	testsupport.RunAndWait(
		&s.Suite,
		func() any {
			s.Nil(SendWithTimeout[ProtocolVersion](s.agentGOB, protocol))
			return nil
		},
		func() any {
			protocol2, err := ReceiveWithTimeout[ProtocolVersion](s.serverGOB)
			s.Nil(err)
			s.Equal(protocol, protocol2)
			return nil
		},
	)
}

func (s *GOBChannelTestSuite) Test_SendInterface() {

	session := NewSessionInfo("abc", "ftp")
	testsupport.RunAndWait(
		&s.Suite,
		func() any {
			s.Nil(SendWithTimeout[ConvergeMessage](s.agentGOB,
				ConvergeMessage{
					Value: session,
				}))
			return nil
		},
		func() any {
			session2, err := ReceiveWithTimeout[ConvergeMessage](s.serverGOB)
			s.Nil(err)
			s.Equal(session, session2.Value)
			return nil
		},
	)
}