package main

import (
	"encoding/json"
	"testing"
)

func TestParseAttachMessage(t *testing.T) {
	data := []byte(`{"attach": "dev-server"}`)
	kind, val := ParseControlMessage(data)
	if kind != "attach" {
		t.Fatalf("expected kind=attach, got %q", kind)
	}
	msg, ok := val.(*AttachMsg)
	if !ok {
		t.Fatalf("expected *AttachMsg, got %T", val)
	}
	if msg.Attach != "dev-server" {
		t.Errorf("expected Attach=%q, got %q", "dev-server", msg.Attach)
	}
}

func TestParseResizeMessage(t *testing.T) {
	data := []byte(`{"resize": {"cols": 120, "rows": 40}}`)
	kind, val := ParseControlMessage(data)
	if kind != "resize" {
		t.Fatalf("expected kind=resize, got %q", kind)
	}
	msg, ok := val.(*ResizeMsg)
	if !ok {
		t.Fatalf("expected *ResizeMsg, got %T", val)
	}
	if msg.Resize.Cols != 120 {
		t.Errorf("expected Cols=120, got %d", msg.Resize.Cols)
	}
	if msg.Resize.Rows != 40 {
		t.Errorf("expected Rows=40, got %d", msg.Resize.Rows)
	}
}

func TestParseDetachMessage(t *testing.T) {
	data := []byte(`{"detach": true}`)
	kind, val := ParseControlMessage(data)
	if kind != "detach" {
		t.Fatalf("expected kind=detach, got %q", kind)
	}
	msg, ok := val.(*DetachMsg)
	if !ok {
		t.Fatalf("expected *DetachMsg, got %T", val)
	}
	if !msg.Detach {
		t.Errorf("expected Detach=true")
	}
}

func TestParseInvalidJSON(t *testing.T) {
	data := []byte(`not json`)
	kind, val := ParseControlMessage(data)
	if kind != "invalid" {
		t.Errorf("expected kind=invalid, got %q", kind)
	}
	if val != nil {
		t.Errorf("expected nil val for invalid, got %v", val)
	}
}

func TestParseUnknownMessage(t *testing.T) {
	data := []byte(`{"foo": "bar"}`)
	kind, val := ParseControlMessage(data)
	if kind != "unknown" {
		t.Errorf("expected kind=unknown, got %q", kind)
	}
	if val != nil {
		t.Errorf("expected nil val for unknown, got %v", val)
	}
}

func TestMarshalAttached(t *testing.T) {
	data := MarshalAttached("dev-server")
	var msg AttachedMsg
	if err := json.Unmarshal(data, &msg); err != nil {
		t.Fatalf("unmarshal: %v", err)
	}
	if msg.Attached != "dev-server" {
		t.Errorf("expected Attached=%q, got %q", "dev-server", msg.Attached)
	}
}

func TestMarshalError(t *testing.T) {
	data := MarshalError("something broke")
	var msg ErrorMsg
	if err := json.Unmarshal(data, &msg); err != nil {
		t.Fatalf("unmarshal: %v", err)
	}
	if msg.Error != "something broke" {
		t.Errorf("expected Error=%q, got %q", "something broke", msg.Error)
	}
}

func TestMarshalExited(t *testing.T) {
	data := MarshalExited("dev-server")
	var msg ExitedMsg
	if err := json.Unmarshal(data, &msg); err != nil {
		t.Fatalf("unmarshal: %v", err)
	}
	if msg.Exited != "dev-server" {
		t.Errorf("expected Exited=%q, got %q", "dev-server", msg.Exited)
	}
}
