package es

import (
	"bytes"
	"encoding/json"
	"strings"
	"testing"

	"github.com/onsi/gomega"
)

func Test_QueryAgg(t *testing.T) {
	qb := NewQueryBuilder("123", nil, NewAggQuery("level"), nil)

	g := gomega.NewWithT(t)

	d, err := qb.Build()
	g.Expect(err).To(gomega.Succeed())

	var m map[string]any
	err = json.Unmarshal(d.Bytes(), &m)
	g.Expect(err).To(gomega.Succeed())

	g.Expect(strings.TrimSpace(d.String())).To(gomega.Equal(bytes.NewBufferString(`{"aggs":{"aggs":{"terms":{"field":"level"}}}}`).String()))
}

func Test_BaseQuery(t *testing.T) {
	//nolint:misspell
	qb := NewQueryBuilder("123", NewBaseQuery().And(NewTermQuery("packageid", "1")), nil, nil)

	g := gomega.NewWithT(t)

	d, err := qb.Build()
	g.Expect(err).To(gomega.Succeed())

	var m map[string]any
	err = json.Unmarshal(d.Bytes(), &m)
	g.Expect(err).To(gomega.Succeed())
	//nolint:misspell
	g.Expect(strings.TrimSpace(d.String())).To(gomega.Equal(bytes.NewBufferString(`{"query":{"bool":{"filter":[{"term":{"packageid":"1"}}]}}}`).String()))
}

func Test_BaseAndAggQuery(t *testing.T) {
	qb := NewQueryBuilder("123",
		NewBaseQuery().
			//nolint:misspell
			And(NewTermQuery("packageid", "1")).
			And(NewTermQuery("level", "info")),
		NewAggQuery("level"), nil)

	g := gomega.NewWithT(t)

	d, err := qb.Build()
	g.Expect(err).To(gomega.Succeed())

	var m map[string]any
	err = json.Unmarshal(d.Bytes(), &m)
	g.Expect(err).To(gomega.Succeed())

	//nolint:misspell
	g.Expect(strings.TrimSpace(d.String())).To(gomega.Equal(bytes.NewBufferString(`{"aggs":{"aggs":{"terms":{"field":"level"}}},"query":{"bool":{"filter":[{"term":{"packageid":"1"}},{"term":{"level":"info"}}]}}}`).String()))
}

func Test_RangeQuery(t *testing.T) {
	//nolint:misspell
	qb := NewQueryBuilder("123",
		NewBaseQuery().
			And(NewTermQuery("packageid", "1")).
			And(NewRangeQuery("level", 1, 1)),
		NewAggQuery("level"), nil)

	g := gomega.NewWithT(t)

	d, err := qb.Build()
	g.Expect(err).To(gomega.Succeed())

	var m map[string]any
	err = json.Unmarshal(d.Bytes(), &m)
	g.Expect(err).To(gomega.Succeed())

	//nolint:misspell
	g.Expect(strings.TrimSpace(d.String())).To(gomega.Equal(bytes.NewBufferString(`{"aggs":{"aggs":{"terms":{"field":"level"}}},"query":{"bool":{"filter":[{"term":{"packageid":"1"}},{"range":{"level":{"gte":1,"lte":1}}}]}}}`).String()))
}

func Test_WildCardQuery(t *testing.T) {
	q := NewBaseQuery().
		And(NewRangeQuery("timestamp", 1, 2)).
		Should(NewWildCardQuery("txn_start_ts", "1*")).
		Should(NewWildCardQuery("digest.keyword", "1*")).
		Should(NewWildCardQuery("prev_stmt.keyword", "1*")).
		Should(NewWildCardQuery("query.keyword", "1*"))

	qb := NewQueryBuilder("123", q, nil, &QueryBuildOption{
		Size: 100,
		Sort: map[string]SortType{
			"timestamp": Desc,
		},
	})

	g := gomega.NewWithT(t)

	d, err := qb.Build()
	g.Expect(err).To(gomega.Succeed())

	var m map[string]any
	err = json.Unmarshal(d.Bytes(), &m)
	g.Expect(err).To(gomega.Succeed())

	g.Expect(strings.TrimSpace(d.String())).To(gomega.Equal(bytes.NewBufferString(`{"query":{"bool":{"filter":[{"range":{"timestamp":{"gte":1,"lte":2}}}],"should":[{"wildcard":{"txn_start_ts":"1*"}},{"wildcard":{"digest.keyword":"1*"}},{"wildcard":{"prev_stmt.keyword":"1*"}},{"wildcard":{"query.keyword":"1*"}}],"minimum_should_match":1}},"size":100,"sort":[{"timestamp":{"order":"desc"}}]}`).String()))
}

func Test_WildCardQueryWithoutFilter(t *testing.T) {
	q := NewBaseQuery().
		// And(NewRangeQuery("timestamp", 1, 2)).
		Should(NewWildCardQuery("txn_start_ts", "1*")).
		Should(NewWildCardQuery("digest.keyword", "1*")).
		Should(NewWildCardQuery("prev_stmt.keyword", "1*")).
		Should(NewWildCardQuery("query.keyword", "1*"))

	qb := NewQueryBuilder("123", q, nil, &QueryBuildOption{
		Size: 100,
		Sort: map[string]SortType{
			"timestamp": Desc,
		},
	})

	g := gomega.NewWithT(t)

	d, err := qb.Build()
	g.Expect(err).To(gomega.Succeed())

	var m map[string]any
	err = json.Unmarshal(d.Bytes(), &m)
	g.Expect(err).To(gomega.Succeed())

	g.Expect(strings.TrimSpace(d.String())).To(gomega.Equal(bytes.NewBufferString(`{"query":{"bool":{"should":[{"wildcard":{"txn_start_ts":"1*"}},{"wildcard":{"digest.keyword":"1*"}},{"wildcard":{"prev_stmt.keyword":"1*"}},{"wildcard":{"query.keyword":"1*"}}],"minimum_should_match":1}},"size":100,"sort":[{"timestamp":{"order":"desc"}}]}`).String()))
}
