package kibana

import (
	"net/http"

	"github.com/cwen0/go-kibana"
	"github.com/pingcap/errors"
)

const (
	namespaceFilter = "kubernetes.namespace_name"
	podNameFilter   = "kubernetes.pod_name"
)

// Config defines the config of kibana service.
type Config struct {
	Address string `toml:"address"`
	Index   string `toml:"index"`
}

// Validate checks if the config is valid.
func (c *Config) Validate() error {
	if len(c.Address) == 0 {
		return errors.New("address of kibana is empty")
	}

	if len(c.Index) == 0 {
		return errors.New("index of kibana is empty")
	}

	return nil
}

// Client defines the client of kibana
type Client struct {
	conf *Config

	client *kibana.Client
}

// NewClient returns a client of kibana
func NewClient(conf *Config) (*Client, error) {
	if err := conf.Validate(); err != nil {
		return nil, errors.Trace(err)
	}

	cli := &Client{
		conf: conf,
	}

	cli.client = kibana.NewClient(&kibana.Config{
		Address: conf.Address,
	}, http.DefaultClient)

	return cli, nil
}

// GenLogURL returns the kibana url according the namespace and podName.
func (c *Client) GenLogURL(namespace, podName string) (string, error) {
	search := &kibana.SearchSource{
		Search: kibana.SearchFields{
			Columns: []string{"log"},
			Sort:    []string{"@timestamp", "desc"},
			Query: kibana.QueryMeta{
				Language: "lucene",
			},
			Index:    c.conf.Index,
			Interval: "auto",
			Filters: []kibana.Filter{
				{
					State: kibana.State{
						Store: "appState",
					},
					Meta: kibana.FilterMeta{
						Disable: false,
						Index:   c.conf.Index,
						Key:     namespaceFilter,
						Negate:  false,
						Params: kibana.FilterParams{
							Query: "",
							Type:  "phrase",
						},
						Type:  "phrase",
						Value: namespace,
					},
					Query: kibana.FilterQueryMeta{
						Match: map[string]kibana.FilterParams{
							namespaceFilter: {
								Query: namespace,
								Type:  "phrase",
							},
						},
					},
				},
				{
					State: kibana.State{
						Store: "appState",
					},
					Meta: kibana.FilterMeta{
						Disable: false,
						Index:   c.conf.Index,
						Key:     podNameFilter,
						Negate:  false,
						Params: kibana.FilterParams{
							Query: podName,
							Type:  "phrase",
						},
						Type:  "phrase",
						Value: podName,
					},
					Query: kibana.FilterQueryMeta{
						Match: map[string]kibana.FilterParams{
							podNameFilter: {
								Query: podName,
								Type:  "phrase",
							},
						},
					},
				},
			},
		},
	}

	url, err := c.client.GenerateURL(search)
	if err != nil {
		return "", errors.Trace(err)
	}

	shortURL, err := c.client.ShortURL(url)
	if err != nil {
		return "", errors.Trace(err)
	}

	return shortURL, nil
}
