// Copyright 2025, IPng Networks GmbH, Pim van Pelt <pim@ipng.ch>

package vppstats

import (
	"flag"
	"fmt"
	"testing"
	"time"

	"go.fd.io/govpp/api"
)

func TestVPPStatsFlags(t *testing.T) {
	// Test default values
	if *ApiAddr != "/var/run/vpp/api.sock" {
		t.Errorf("Expected default API address to be '/var/run/vpp/api.sock', got '%s'", *ApiAddr)
	}
	
	if *StatsAddr != "/var/run/vpp/stats.sock" {
		t.Errorf("Expected default stats address to be '/var/run/vpp/stats.sock', got '%s'", *StatsAddr)
	}
	
	if *IfIndexOffset != 1000 {
		t.Errorf("Expected default interface index offset to be 1000, got %d", *IfIndexOffset)
	}
	
	if *Period != 10 {
		t.Errorf("Expected default period to be 10, got %d", *Period)
	}
}

func TestFlagRegistrations(t *testing.T) {
	tests := []struct {
		name     string
		flagName string
		defValue string
	}{
		{"API address", "vppstats.api.addr", "/var/run/vpp/api.sock"},
		{"Stats address", "vppstats.stats.addr", "/var/run/vpp/stats.sock"},
		{"Index offset", "vppstats.ifindex-offset", "1000"},
		{"Period", "vppstats.period", "10"},
	}
	
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			f := flag.Lookup(tt.flagName)
			if f == nil {
				t.Errorf("Expected %s flag to be registered", tt.flagName)
				return
			}
			
			if f.DefValue != tt.defValue {
				t.Errorf("Expected %s flag default value to be '%s', got '%s'", 
					tt.flagName, tt.defValue, f.DefValue)
			}
		})
	}
}

func TestStatsCallbackType(t *testing.T) {
	// Test that we can create a valid callback function
	var called bool
	var receivedStats *api.InterfaceStats
	
	callback := func(stats *api.InterfaceStats) {
		called = true
		receivedStats = stats
	}
	
	// Create mock stats
	mockStats := &api.InterfaceStats{
		Interfaces: []api.InterfaceCounters{
			{
				InterfaceIndex: 1,
				InterfaceName:  "test",
			},
		},
	}
	
	// Call the callback
	callback(mockStats)
	
	if !called {
		t.Error("Expected callback to be called")
	}
	
	if receivedStats != mockStats {
		t.Error("Expected callback to receive the same stats object")
	}
	
	if len(receivedStats.Interfaces) != 1 {
		t.Errorf("Expected 1 interface, got %d", len(receivedStats.Interfaces))
	}
	
	if receivedStats.Interfaces[0].InterfaceName != "test" {
		t.Errorf("Expected interface name 'test', got '%s'", receivedStats.Interfaces[0].InterfaceName)
	}
}

func TestPeriodConversion(t *testing.T) {
	// Test that period conversion works correctly
	originalPeriod := *Period
	defer func() { *Period = originalPeriod }()
	
	testPeriods := []struct {
		input    int
		expected time.Duration
	}{
		{1, time.Second},
		{5, 5 * time.Second},
		{10, 10 * time.Second},
		{60, time.Minute},
	}
	
	for _, tt := range testPeriods {
		t.Run(fmt.Sprintf("period_%d", tt.input), func(t *testing.T) {
			*Period = tt.input
			result := time.Duration(*Period) * time.Second
			
			if result != tt.expected {
				t.Errorf("Expected period %v, got %v", tt.expected, result)
			}
		})
	}
}

func TestFlagValues(t *testing.T) {
	// Save original flag values
	originalApiAddr := *ApiAddr
	originalStatsAddr := *StatsAddr
	originalOffset := *IfIndexOffset
	originalPeriod := *Period
	
	defer func() {
		*ApiAddr = originalApiAddr
		*StatsAddr = originalStatsAddr
		*IfIndexOffset = originalOffset
		*Period = originalPeriod
	}()
	
	// Test setting flag values
	*ApiAddr = "/custom/api.sock"
	*StatsAddr = "/custom/stats.sock"
	*IfIndexOffset = 2000
	*Period = 30
	
	if *ApiAddr != "/custom/api.sock" {
		t.Errorf("Expected API address to be '/custom/api.sock', got '%s'", *ApiAddr)
	}
	
	if *StatsAddr != "/custom/stats.sock" {
		t.Errorf("Expected stats address to be '/custom/stats.sock', got '%s'", *StatsAddr)
	}
	
	if *IfIndexOffset != 2000 {
		t.Errorf("Expected interface index offset to be 2000, got %d", *IfIndexOffset)
	}
	
	if *Period != 30 {
		t.Errorf("Expected period to be 30, got %d", *Period)
	}
}