package resourcemanager

import (
	"context"
	"fmt"

	"github.com/patrickmn/go-cache"
	"github.com/prometheus/client_golang/api"
	v1 "github.com/prometheus/client_golang/api/prometheus/v1"
	"github.com/prometheus/common/model"
)

type cachedPrometheusAPIClient struct {
	promClientPool *cache.Cache
}

func (c *cachedPrometheusAPIClient) Alerts(url string, ctx context.Context) (v1.AlertsResult, error) {
	var result v1.AlertsResult
	cli, err := c.getPromAPI(url)
	if err != nil {
		return result, fmt.Errorf("Get Prometheus client with url %s error %w", url, err)
	}
	return cli.Alerts(ctx)
}

func (c *cachedPrometheusAPIClient) QueryRange(url string, ctx context.Context, query string, r v1.Range, opts ...v1.Option) (model.Value, v1.Warnings, error) {
	var result model.Value
	cli, err := c.getPromAPI(url)
	if err != nil {
		return result, nil, fmt.Errorf("Get Prometheus client with url %s error %w", url, err)
	}
	return cli.QueryRange(ctx, query, r, opts...)
}

func (c *cachedPrometheusAPIClient) getPromAPI(url string) (v1.API, error) {
	cli, exists := c.promClientPool.Get(url)
	if !exists {
		cli, err := newPromClient(url)
		if err != nil {
			return nil, err
		}
		c.promClientPool.SetDefault(url, cli)
		return cli, nil
	}
	return cli.(v1.API), nil
}

func newPromClient(url string) (v1.API, error) {
	apiClient, err := api.NewClient(api.Config{
		Address: url,
	})

	if err != nil {
		return nil, err
	}
	return v1.NewAPI(apiClient), nil
}
