package slowlogagg

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v6"
	"github.com/pingcap/log"
	"github.com/pingcap/tep/pkg/utils"
	query2 "github.com/pingcap/tep/pkg/utils/es/query"
	"github.com/wushilin/stream"
	"go.uber.org/zap"
	"strings"
	"time"
)

type slowAggQuery struct {
	from      int
	startTime string
	endTime   string
	items     []interface{}
}

type SlowAggQuery func(q *slowAggQuery)

func NewSlowAggQuery(q ...SlowAggQuery) *slowAggQuery {
	tidbQ := &slowAggQuery{}
	stream.FromArray(q).Each(func(f interface{}) {
		f.(SlowAggQuery)(tidbQ)
	})

	return tidbQ
}

func From(from int) SlowAggQuery {
	if from < 0 {
		from = 0
	}

	return func(q *slowAggQuery) {
		q.from = from
	}
}

func StartTimeInSec(startTimeInSec int64) SlowAggQuery {
	if startTimeInSec <= 0 {
		startTimeInSec = time.Now().Unix() - 15*60
	}

	return func(q *slowAggQuery) {
		q.startTime = query2.ConvertTimeStamp(startTimeInSec)
	}
}

func EndTimeInSec(endTimeInSec int64) SlowAggQuery {
	if endTimeInSec <= 0 {
		endTimeInSec = time.Now().Unix()
	}

	return func(q *slowAggQuery) {
		q.endTime = query2.ConvertTimeStamp(endTimeInSec)
	}
}

func Items(items []interface{}) SlowAggQuery {
	return func(q *slowAggQuery) {
		q.items = items
	}
}

func (q *slowAggQuery) Do(client *elasticsearch.Client, indexPrefix string) (*query2.QueryResponse, error) {
	qs := query2.NewQueryBuilder().
		AddRange("@timestamp", q.startTime, q.endTime).
		AddIn("kubernetes.namespace_name", q.items).
		GetQuery()

	qb := fmt.Sprintf(query, qs)

	res, err := client.Search(
		client.Search.WithContext(context.Background()),
		client.Search.WithIndex(fmt.Sprintf("%s*", indexPrefix)),
		client.Search.WithBody(strings.NewReader(qb)),
		client.Search.WithPretty(),
	)

	if err != nil {
		log.Error("Query from es failed", zap.Error(err))
		return nil, err
	}
	defer utils.CallDeferMethod(res.Body.Close, "close response body failed")
	return query2.NewResponse(res.Body), nil
}

const query = `
 {"size":0,
  "query": %s,
  "aggs":{
    "ns_count":{
      "terms":{
        "field":"kubernetes.namespace_name.keyword",
        "order": [
          {
            "_count": "desc"
          }
          ],
 		"size":2147483647
      }
    }
  }
}
`
