package debug

import (
	"context"
	"fmt"
	"net/url"
	"strings"

	"github.com/pingcap/dbaas/central/config"
	"github.com/pingcap/dbaas/central/db"
	"github.com/pingcap/dbaas/central/db/entity"
	"github.com/pingcap/dbaas/central/model/admin/grafana"
	"gorm.io/gorm"
)

type DashboardLink struct {
	Name string
	Link string
}

func (m *Model) GetDashboardLinks(tenantID, clusterID uint64) ([]DashboardLink, error) {
	// FIXME: Currently this is completely copied from admin model.
	var (
		t       entity.Tenant
		cluster entity.Cluster
	)
	err := db.Transaction(func(tx *gorm.DB) error {
		err := entity.NewTenantQuerySet(tx).IDEq(entity.ID(tenantID)).One(&t)
		if err != nil {
			return err
		}
		return entity.NewClusterQuerySet(tx).
			StatusNotIn(entity.ClusterStatusDeleted, entity.ClusterStatusCleared). // do we really need filter by this?
			IDEq(entity.ID(clusterID)).One(&cluster)
	})
	if err != nil {
		return nil, err
	}

	params := []grafana.SearchParam{
		grafana.SearchType(grafana.SearchTypeDashboard),
		grafana.SearchQuery(""),
		grafana.SearchStarred(false),
	}
	params = append(params, grafana.SearchTag(config.Global().GrafanaConfig.TidbDashboardTag))
	items, err := m.grafanaClient.Search(context.TODO(), params...)
	if err != nil {
		return nil, err
	}
	grafanaServer := strings.TrimSuffix(config.Global().GrafanaConfig.Server, "/")
	var ds []DashboardLink
	for _, item := range items {
		ds = append(ds, DashboardLink{Name: item.Title, Link: fmt.Sprintf("%s%s?%s", grafanaServer, item.URL, buildGrafanaDashboardURLQueryParameter(t.Name, cluster.Name, tenantID, clusterID))})
	}
	return ds, nil
}

func buildGrafanaDashboardURLQueryParameter(tenantName, clusterName string, tenantID, clusterID uint64) string {
	// FIXME: Currently this is completely copied from admin model.
	u := url.URL{}
	q := u.Query()
	q.Add("var-tenant_name", tenantName)
	q.Add("var-tenant_id", fmt.Sprintf("%d", tenantID))
	q.Add("var-cluster_name", clusterName)
	q.Add("var-cluster_id", fmt.Sprintf("%d", clusterID))
	return q.Encode()
}
