package mxgateway

import (
	"encoding/json"
	"os"
	"path/filepath"
	"testing"

	pb "gitea.dohertylan.com/dohertj2/mxaccessgw/clients/go/internal/generated"
	"google.golang.org/protobuf/encoding/protojson"
)

func TestValueConversionFixtures(t *testing.T) {
	data, err := os.ReadFile(filepath.Join("..", "..", "proto", "fixtures", "behavior", "values", "value-conversion-cases.json"))
	if err != nil {
		t.Fatalf("read fixture: %v", err)
	}

	var fixture struct {
		Cases []struct {
			ID           string          `json:"id"`
			ExpectedKind string          `json:"expectedKind"`
			Value        json.RawMessage `json:"value"`
		} `json:"cases"`
	}
	if err := json.Unmarshal(data, &fixture); err != nil {
		t.Fatalf("parse fixture manifest: %v", err)
	}

	for _, tc := range fixture.Cases {
		t.Run(tc.ID, func(t *testing.T) {
			var value pb.MxValue
			if err := protojson.Unmarshal(tc.Value, &value); err != nil {
				t.Fatalf("parse value: %v", err)
			}
			if _, err := NativeValue(&value); err != nil {
				t.Fatalf("NativeValue() error = %v", err)
			}
			if got := value.ProtoReflect().WhichOneof(value.ProtoReflect().Descriptor().Oneofs().ByName("kind")).JSONName(); got != tc.ExpectedKind {
				t.Fatalf("kind = %q, want %q", got, tc.ExpectedKind)
			}
		})
	}
}

func TestStatusConversionFixtures(t *testing.T) {
	data, err := os.ReadFile(filepath.Join("..", "..", "proto", "fixtures", "behavior", "statuses", "status-conversion-cases.json"))
	if err != nil {
		t.Fatalf("read fixture: %v", err)
	}

	var fixture struct {
		Cases []struct {
			ID          string          `json:"id"`
			WantSuccess bool            `json:"wantSuccess"`
			Status      json.RawMessage `json:"status"`
		} `json:"cases"`
	}
	if err := json.Unmarshal(data, &fixture); err != nil {
		t.Fatalf("parse fixture manifest: %v", err)
	}

	for _, tc := range fixture.Cases {
		t.Run(tc.ID, func(t *testing.T) {
			var status pb.MxStatusProxy
			if err := protojson.Unmarshal(tc.Status, &status); err != nil {
				t.Fatalf("parse status: %v", err)
			}
			if got := StatusSucceeded(&status); got != tc.WantSuccess {
				t.Fatalf("StatusSucceeded() = %v, want %v", got, tc.WantSuccess)
			}
		})
	}
}
