package configs

import (
	"errors"
	"fmt"
	"time"
)

type Sources struct {
	VictoriaMetrics *VictoriaMetrics `toml:"victoriametrics"`
}

func (c *Sources) Validate() error {
	if c.VictoriaMetrics != nil {
		return c.VictoriaMetrics.Validate()
	}
	return fmt.Errorf("no sources configured")
}

func (c *Sources) Shards() []MetricShard {
	if c.VictoriaMetrics != nil && c.VictoriaMetrics.Enabled {
		return c.VictoriaMetrics.Shards()
	}
	return nil
}

type VictoriaMetrics struct {
	Enabled      bool     `toml:"enabled"`
	Endpoint     string   `toml:"endpoint"`
	Timeout      Duration `toml:"timeout"`
	TimeInterval Duration `toml:"timeInterval"`
	Match        string   `toml:"match"`
	StartTime    int64    `toml:"startTime"`
	EndTime      int64    `toml:"endTime"`
}

func (c *VictoriaMetrics) Validate() error {
	if c.Match == "" {
		c.Match = defaultVmMatch
	}
	if c.Endpoint == "" {
		return errors.New("victoriametrics.endpoint is required")
	}
	if c.Timeout <= 0 {
		c.Timeout = Duration(defaultVmTimeout)
	}
	if c.StartTime <= 0 {
		return errors.New("victoriametrics.startTime must be > 0")
	}
	if c.EndTime <= c.StartTime {
		return errors.New("victoriametrics.endTime must be > startTime")
	}
	if c.TimeInterval <= 0 {
		c.TimeInterval = Duration(defaultVmInterval)
	}
	return nil
}

// Shards generates time-based partitions for the backup window.
//
// The algorithm ensures complete coverage from StartTime to EndTime without gaps
// or overlaps, with the final shard truncated to EndTime if the interval doesn't
// divide evenly.
func (c *VictoriaMetrics) Shards() []MetricShard {
	var shards []MetricShard
	interval := int64(time.Duration(c.TimeInterval).Seconds())

	var index int
	for cur := c.StartTime; cur < c.EndTime; cur += interval {
		next := cur + interval
		if next > c.EndTime {
			next = c.EndTime
		}
		shards = append(shards, MetricShard{Index: index, Start: cur, End: next})
		index++
	}
	return shards
}
