package cbbclient

import (
	"a.yandex-team.ru/balancer/production/x/iptables_daemon/daemonmetrics"
	"a.yandex-team.ru/library/go/core/log"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"time"
)

type IClient interface {
	WaitForReadiness(log.Logger) <-chan time.Time
	Fetch(daemonmetrics.IMetrics, log.Logger) (io.ReadCloser, error)
	Reset()
	UpdateLastTS(uint64)
}

type Client struct {
	getQuery            string
	lastChangeTimestamp uint64
	refreshIntervalSec  int64
}

func (c *Client) Reset() {
	c.lastChangeTimestamp = 0
}

func (c *Client) UpdateLastTS(ts uint64) {
	if c.lastChangeTimestamp < ts {
		c.lastChangeTimestamp = ts
	}
}

func (c *Client) WaitForReadiness(logger log.Logger) <-chan time.Time {
	toSleep := c.refreshIntervalSec + rand.Int63n(c.refreshIntervalSec/5)
	logger.Infof("CBBClient::WaitForReadiness: Sleeping for %d seconds", toSleep)
	return time.After(time.Second * time.Duration(toSleep))
}

func (c *Client) Fetch(metrics daemonmetrics.IMetrics, logger log.Logger) (io.ReadCloser, error) {
	defer func(start time.Time, name string) {
		elapsed := time.Since(start).Milliseconds()
		logger.Infof("Execution of %s took %d ms", name, elapsed)
		metrics.ReportExecTimeMs(fmt.Sprintf("exec%sTimeMs", name), float64(elapsed))
	}(time.Now(), "FetchCBBResponse")
	url := fmt.Sprintf("http://"+c.getQuery, c.lastChangeTimestamp)
	logger.Infof("Fetching cbb response from \"%s\"", url)
	httpClient := http.Client{
		Timeout: 5 * time.Second,
	}
	resp, err := httpClient.Get(url)
	if err != nil {
		return nil, err
	}

	return resp.Body, nil
}

func New(getQuery string, refreshIntervalSec int64) IClient {
	return &Client{
		getQuery:            getQuery,
		refreshIntervalSec:  refreshIntervalSec,
		lastChangeTimestamp: 0}

}
