package resourcemanager

import (
	"context"
	"testing"
	"time"

	"github.com/patrickmn/go-cache"
	promv1 "github.com/prometheus/client_golang/api/prometheus/v1"
	"github.com/stretchr/testify/assert"
	prommock "github.com/tidbcloud/observability/pkg/resourcemanager/fake"
	"go.uber.org/mock/gomock"
)

var (
	badUrl  = ":example.com/path?query=value"
	testUrl = "http://test:9090"
)

func TestAlerts(t *testing.T) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	promAPI := prommock.NewMockAPI(ctrl)

	client := prometheusAPIClient.(*cachedPrometheusAPIClient)
	client.promClientPool.SetDefault(testUrl, promAPI)

	t.Run("failed get api client", func(t *testing.T) {
		_, err := prometheusAPIClient.Alerts(badUrl, context.TODO())
		assert.Error(t, err)
	})
	t.Run("success", func(t *testing.T) {
		promAPI.EXPECT().
			Alerts(gomock.Any()).
			Return(promv1.AlertsResult{
				Alerts: []promv1.Alert{
					promv1.Alert{},
				},
			}, nil).
			Times(1)
		res, err := prometheusAPIClient.Alerts(testUrl, context.TODO())
		assert.NoError(t, err)
		assert.Equal(t, len(res.Alerts), 1)
	})
}

func TestQueryRange(t *testing.T) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	promAPI := prommock.NewMockAPI(ctrl)
	client := prometheusAPIClient.(*cachedPrometheusAPIClient)
	client.promClientPool.SetDefault(testUrl, promAPI)

	r := promv1.Range{}
	t.Run("failed get api client", func(t *testing.T) {
		_, _, err := prometheusAPIClient.QueryRange(badUrl, context.TODO(), "up", r)
		assert.Error(t, err)
	})
	t.Run("success", func(t *testing.T) {
		promAPI.EXPECT().
			QueryRange(gomock.Any(), gomock.Any(), gomock.Any()).
			Return(nil, nil, nil).
			Times(1)
		_, _, err := prometheusAPIClient.QueryRange(testUrl, context.TODO(), "up", r)
		assert.NoError(t, err)
	})
}

func TestGetPromAPI(t *testing.T) {

	cli := &cachedPrometheusAPIClient{
		promClientPool: cache.New(time.Hour, 6*time.Hour),
	}
	t.Run("error with bad url", func(t *testing.T) {
		_, err := cli.getPromAPI(badUrl)
		assert.Error(t, err)
	})

	t.Run("get client", func(t *testing.T) {
		_, err := cli.getPromAPI(testUrl)
		assert.NoError(t, err)
		_, err = cli.getPromAPI(testUrl)
		assert.NoError(t, err)
	})

}
