package agentd

import (
	"context"
	"time"

	agentv1 "github.com/wangjia/pangolin/server/internal/pb/agentv1"
)

// UsageSource yields per-dp_uuid aggregate counters for the elapsed window. It
// MUST return only dp_uuids and byte/minute counts — never user ids, addresses or
// DNS. The default returns nothing (no stats backend wired); production plugs in a
// sing-box stats reader.
type UsageSource interface {
	// Collect drains and returns usage accumulated since the previous call.
	Collect() []*agentv1.UsageEntry
}

// nopUsageSource reports nothing.
type nopUsageSource struct{}

func (nopUsageSource) Collect() []*agentv1.UsageEntry { return nil }

// runUsage periodically aggregates and uploads usage. Reporting failures are
// logged but do not tear down the session (usage is best-effort, at-least-once).
func (a *Agent) runUsage(ctx context.Context, client agentv1.AgentServiceClient) error {
	ticker := time.NewTicker(a.cfg.UsageInterval)
	defer ticker.Stop()
	windowStart := a.clock().Unix()
	for {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-ticker.C:
		}
		entries := a.usage.Collect()
		if len(entries) == 0 {
			windowStart = a.clock().Unix()
			continue
		}
		now := a.clock().Unix()
		_, err := client.ReportUsage(ctx, &agentv1.UsageReport{
			NodeUUID:        a.NodeUUID(),
			WindowStartUnix: windowStart,
			WindowEndUnix:   now,
			Entries:         entries,
		})
		if err != nil {
			// Connection-level errors should restart the session; surface them.
			return err
		}
		windowStart = now
	}
}
