package mo

import (
	"encoding/json"
	"testing"

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

func TestMatchBuilder(t *testing.T) {
	match := Matcher{}
	match.In("fruit", A{"apple", "orange", "banana"})
	match.Nin("fruit", A{"pear"})
	match.Eq("name", "admin")
	match.Ne("role", "user")
	match.Gt("age", 10)
	match.Gte("age", 11)
	match.Lt("age", 12)
	match.Lte("age", 13)
	match.All("security", A{"SSL", "TLS"})
	match.Regex("regexp", "/^S/", "m")
	match.Not("regexp", "/^p.*/")
	em := new(Matcher)
	em.Eq("name", "1111")
	match.ElemMatch("elem", em)

	or := Matcher{}
	or.Gt("age", 10)
	or.Lt("age", 20)
	match.Or(&or)

	and := Matcher{}
	and.Add("tags", "ssl")
	and.Add("tags", "security")
	match.And(&and)

	nor := (&Matcher{}).Lte("nor", 100).Gte("nor", 50)
	match.Nor(nor)

	done := match.Done()
	pipeline := match.Pipeline()
	t.Log(done)
	t.Log(pipeline)

	b, err := json.Marshal(&match)
	if err == nil {
		t.Log("Marshal:", string(b))
	}

	if _, err = bson.Marshal(done); err != nil {
		t.Error(err)
		return
	}
	if _, err = bson.Marshal(pipeline); err != nil {
		t.Error(err)
		return
	}
}

func TestGroupBuilder(t *testing.T) {
	group := Grouper{}
	group.Add("_id", ID.New())
	group.Add("count", D{{Key: "$sum", Value: 1}})

	done := group.Done()
	pipeline := group.Pipeline()

	t.Log(done)
	t.Log(pipeline)

	if _, err := bson.Marshal(done); err != nil {
		t.Error(err)
	}
	if _, err := bson.Marshal(pipeline); err != nil {
		t.Error(err)
	}
}

func TestProjectBuilder(t *testing.T) {
	p := Projects{}
	p.AddDisable(OID)

	done := p.Done()
	pipeline := p.Pipeline()

	t.Log(done)
	t.Log(pipeline)

	if _, err := bson.Marshal(done); err != nil {
		t.Error(err)
	}
	if _, err := bson.Marshal(pipeline); err != nil {
		t.Error(err)
	}
}

func TestSortBuilder(t *testing.T) {
	s := Sorter{}
	s.AddASC("age")
	s.AddDESC("updateTime")

	done := s.Done()
	pipeline := s.Pipeline()

	t.Log(done)
	t.Log(pipeline)

	if _, err := bson.Marshal(done); err != nil {
		t.Error(err)
	}
	if _, err := bson.Marshal(pipeline); err != nil {
		t.Error(err)
	}
}

func TestLimitBuilder(t *testing.T) {
	l := &Limiter{Limit: 10}

	pipeline := l.Pipeline()

	t.Log(pipeline)

	if _, err := bson.Marshal(pipeline); err != nil {
		t.Error(err)
	}
}

func TestSkipBuilder(t *testing.T) {
	s := NewSkip(20)

	pipeline := s.Pipeline()

	t.Log(pipeline)

	if _, err := bson.Marshal(pipeline); err != nil {
		t.Error(err)
	}
}

func TestLookupBuilder(t *testing.T) {
	l := Looker{}
	l.SetFrom("user")
	l.SetLocalField("sn")
	l.SetForeignField("name")
	l.SetAs("name")

	pipeline := l.Pipeline()

	t.Log(pipeline)

	if _, err := bson.Marshal(pipeline); err != nil {
		t.Error(err)
	}
}

func TestAddSetter_SUM(t *testing.T) {
	s := Setter{}
	s.SUM("total", []string{"num1", "num2", "num3"})

	pipeline := s.Pipeline()

	t.Log(pipeline)

	if _, err := bson.Marshal(pipeline); err != nil {
		t.Error(err)
	}
}

func TestNewPipeline(t *testing.T) {
	l := &Limiter{Limit: 10}
	s := &Skipper{Skip: 20}

	pipe := NewPipeline(s, l)
	t.Log(pipe)
}
