package query

import (
	"encoding/json"
	"fmt"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/yalp/jsonpath"
)

func TestEquivalentQuery(t *testing.T) {
	q := NewQueryBuilder()

	q.AddEqual("Level", "error").
		AddEqual("Source", "po.go").
		AddEqual("Line", 129)

	qstatement := q.BuildQuery()

	var qj interface{}
	json.Unmarshal([]byte(qstatement), &qj)

	expect := make(map[string]interface{})
	for i := 0; i < 3; i++ {
		path, _ := jsonpath.Read(qj, fmt.Sprintf("$.query.bool.filter[%d].term", i))
		if m, ok := path.(map[string]interface{}); ok {
			for key, value := range m {
				expect[key] = value
			}
		}
	}

	assert := assert.New(t)

	assert.Equal(expect["Level"], "error")
	assert.Equal(expect["Source"], "po.go")
	assert.Equal(expect["Line"], float64(129))
}

func TestRangeQuery(t *testing.T) {
	qb := NewQueryBuilder()

	qb.AddRange("timestamp", "2019-04-21", "now").
		AddEqual("Level", "error").
		AddEqual("Source", "po.go").
		AddEqual("Line", 129)

	qstatement := qb.BuildQuery()

	var qj interface{}
	json.Unmarshal([]byte(qstatement), &qj)

	expectTerm := make(map[string]interface{})
	var expectRangeMin, expectRangeMax string
	for i := 0; i < 4; i++ {
		if path, err := jsonpath.Read(qj, fmt.Sprintf("$.query.bool.filter[%d].term", i)); err == nil {
			if m, ok := path.(map[string]interface{}); ok {
				for key, value := range m {
					expectTerm[key] = value
				}
			}
		}

		if path, err := jsonpath.Read(qj, fmt.Sprintf("$.query.bool.filter[%d].range.timestamp.gte", i)); err == nil {
			if str, ok := path.(string); ok {
				expectRangeMin = str
			}
		}

		if path, err := jsonpath.Read(qj, fmt.Sprintf("$.query.bool.filter[%d].range.timestamp.lte", i)); err == nil {
			if str, ok := path.(string); ok {
				expectRangeMax = str
			}
		}
	}

	assert := assert.New(t)

	assert.Equal(expectTerm["Level"], "error")
	assert.Equal(expectTerm["Source"], "po.go")
	assert.Equal(expectTerm["Line"], float64(129))

	assert.Equal(expectRangeMin, "2019-04-21")
	assert.Equal(expectRangeMax, "now")
}
