package poller

import (
	"fmt"
	"net/http"
	"time"

	"github.com/featurebasedb/featurebase/v3/dax"
	"github.com/featurebasedb/featurebase/v3/logger"
)

// NodePoller is an interface to anything which has the ability to poll a
// node.
type NodePoller interface {
	Poll(dax.Address) bool
}

// Ensure type implements interface.
var _ NodePoller = (*NopNodePoller)(nil)
var _ NodePoller = (*HTTPNodePoller)(nil)

// NopNodePoller is a no-op implementation of the NodePoller interface.
type NopNodePoller struct{}

func NewNopNodePoller() *NopNodePoller {
	return &NopNodePoller{}
}

func (p *NopNodePoller) Poll(addr dax.Address) bool {
	return true
}

// HTTPNodePoller is an http implementation of the NodePoller interface.
type HTTPNodePoller struct {
	logger logger.Logger
	client *http.Client
}

func NewHTTPNodePoller(logger logger.Logger) *HTTPNodePoller {
	return &HTTPNodePoller{
		logger: logger,
		client: &http.Client{
			Timeout: time.Second, // short timeout for polling to detect issues quickly. /health endpoints should always respond fast.
		},
	}
}

func (p *HTTPNodePoller) Poll(addr dax.Address) bool {
	url := fmt.Sprintf("%s/health", addr.WithScheme("http"))

	if resp, err := p.client.Get(url); err != nil {
		p.logger.Printf("poll error: %s\n", err)
		return false
	} else if resp.StatusCode != http.StatusOK {
		return false
	}

	return true
}
