package entity

import (
	"fmt"
	"testing"

	"go.mongodb.org/mongo-driver/bson"
)

func TestOne(t *testing.T) {
	one := One{
		Name: "myname",
		Type: "mytype",
	}
	q := one.Query()
	if want := fmt.Sprint(One{Name: one.Name}); want != fmt.Sprint(q) {
		t.Error(want, q)
	}
}

func TestOneMarshalBSON(t *testing.T) {
	cases := map[string]struct {
		sameAsQuery bool
		one         One
	}{
		"query no modified change": {
			sameAsQuery: true,
			one:         (One{Name: "hello", Type: "world", Modified: 1}).Query(),
		},
		"modified changes": {
			one: One{Name: "hello", Type: "world", Modified: 1},
		},
		"w/ connections": {
			one: One{Name: "hello", Type: "world", Modified: 1, Connections: map[string]One{"hi": One{Name: "hi", Relationship: "mom"}}},
		},
		"w/ attachments": {
			one: One{Name: "hello", Type: "world", Modified: 1, Attachments: map[string]string{"hello": "/world"}},
		},
	}

	for name, d := range cases {
		c := d
		t.Run(name, func(t *testing.T) {
			var bm bson.Marshaler = c.one
			t.Log(bm)
			b, err := bson.Marshal(c.one)
			if err != nil {
				t.Fatal(err)
			}
			one := One{}
			if err := bson.Unmarshal(b, &one); err != nil {
				t.Fatal(err)
			}
			if c.sameAsQuery && (fmt.Sprint(one) != fmt.Sprint(one.Query()) || fmt.Sprint(one) != fmt.Sprint(c.one)) {
				t.Error(c.sameAsQuery, c.one, one)
			} else if !c.sameAsQuery {
				if c.one.Modified == one.Modified {
					t.Error(c.one.Modified, one.Modified)
				}
				c.one.Modified = 0
				one.Modified = 0
				for k := range one.Connections {
					temp := one.Connections[k]
					temp.Modified = 0
					one.Connections[k] = temp
				}
				if fmt.Sprint(c.one) != fmt.Sprint(one) {
					t.Error(c.one, one)
				}
			}
		})
	}
}
