package operator

import (
	"testing"

	"google.golang.org/protobuf/proto"

	altv1 "git.toki-labs.com/toki/alt/packages/contracts/gen/go/alt/v1"
	protoSocket "git.toki-labs.com/toki/proto-socket/go"
)

func TestParserMapIncludesRunnerMessages(t *testing.T) {
	pm := ParserMap()

	required := []proto.Message{
		&altv1.HelloRequest{},
		&altv1.HelloResponse{},
		&altv1.ListInstrumentsRequest{},
		&altv1.ListInstrumentsResponse{},
		&altv1.ListBarsRequest{},
		&altv1.ListBarsResponse{},
		// market import command surface a later CLI subtask sends/receives
		&altv1.ImportDailyBarsRequest{},
		&altv1.ImportDailyBarsResponse{},
		// backtest surface is parsed too so the CLI rail matches the API/worker
		// parser maps and a later subtask can reuse it without drift.
		&altv1.StartBacktestRequest{},
		&altv1.GetBacktestResultResponse{},
		&altv1.CompareBacktestRunsResponse{},
		// paper trading surface is parsed too so the CLI rail matches the
		// API/worker parser maps for paper start/state without drift.
		&altv1.StartPaperTradingRequest{},
		&altv1.StartPaperTradingResponse{},
		&altv1.GetPaperTradingStateRequest{},
		&altv1.GetPaperTradingStateResponse{},
		&altv1.PaperTradingState{},
		// paper order lifecycle surface: submit / cancel / fill
		&altv1.SubmitPaperOrderRequest{},
		&altv1.SubmitPaperOrderResponse{},
		&altv1.CancelPaperOrderRequest{},
		&altv1.CancelPaperOrderResponse{},
		&altv1.FillPaperOrderRequest{},
		&altv1.FillPaperOrderResponse{},
		// live trading surface: broker capability probe
		&altv1.GetLiveBrokerCapabilitiesRequest{},
		&altv1.GetLiveBrokerCapabilitiesResponse{},
		&altv1.LiveBrokerCapability{},
	}
	for _, m := range required {
		name := protoSocket.TypeNameOf(m)
		if _, ok := pm[name]; !ok {
			t.Errorf("parser map missing %q", name)
		}
	}
}

func TestParserMapRoundTripsHelloResponse(t *testing.T) {
	pm := ParserMap()
	name := protoSocket.TypeNameOf(&altv1.HelloResponse{})
	parser, ok := pm[name]
	if !ok {
		t.Fatalf("parser map missing %q", name)
	}

	data, err := proto.Marshal(&altv1.HelloResponse{ServerName: "alt-api", Capabilities: []string{"hello"}})
	if err != nil {
		t.Fatalf("marshal: %v", err)
	}
	msg, err := parser(data)
	if err != nil {
		t.Fatalf("parse: %v", err)
	}
	resp, ok := msg.(*altv1.HelloResponse)
	if !ok {
		t.Fatalf("parsed %T, want *altv1.HelloResponse", msg)
	}
	if resp.GetServerName() != "alt-api" {
		t.Errorf("server name = %q, want alt-api", resp.GetServerName())
	}
}
