package servicecatalog

import (
	"context"
	"time"

	"code.justin.tv/eventbus/controlplane/internal/environment"
	"code.justin.tv/eventbus/controlplane/internal/logger"

	"github.com/pkg/errors"
	"go.uber.org/zap"
)

const (
	expiry            = 24 * time.Hour // how long items should be cached
	cacheMaxSize      = 5000
	cacheItemsToPrune = 20
	pollInterval      = 1 * time.Hour
	retries           = 5
)

type NonExistentService struct{}

func (s *ServiceCatalog) poll() {
	log := logger.FromContext(context.Background())
	env := environment.Environment()
	if !(environment.IsStagingEnv(env) || environment.IsProductionEnv(env)) {
		log.Info("Disabling fetching from service catalog")
		return
	}

	t := time.NewTicker(pollInterval)
	defer t.Stop()
	for {
		for i := 0; i < retries; i++ {
			ctx := context.Background()
			err := s.populateCache(ctx)
			if err != nil {
				log.Warn("could not fetch services from service catalog", zap.Error(err))
			} else {
				break
			}
		}

		select {
		case <-s.done:
			return
		case <-t.C:
		}
	}
}

func (s *ServiceCatalog) populateCache(ctx context.Context) error {
	services, err := s.fetcher.fetchServices(ctx)
	if err != nil {
		return errors.Wrap(err, "could not fetch services")
	}

	for _, serv := range services {
		r := Response{
			Name:        serv.Name,
			Description: serv.Description,
			Slack:       serv.SlackChannel.Name,
			Pagerduty:   serv.Pagerduty,
		}
		s.cache.Set(serv.ID, &r, expiry)
	}

	return nil
}

func (s *ServiceCatalog) cacheMissingService(serviceCatalogID string) {
	s.cache.Set(serviceCatalogID, &NonExistentService{}, expiry)
}
