package platform

import "time"

// BenchmarkHostConfig holds static CPU and memory configuration captured at
// benchmark start. Useful for correlating results across runs on different hardware.
type BenchmarkHostConfig struct {
	CPUModel    string  `json:"cpu_model,omitempty"`
	CPUSockets  int     `json:"cpu_sockets,omitempty"`
	CPUCores    int     `json:"cpu_cores,omitempty"`
	CPUThreads  int     `json:"cpu_threads,omitempty"`
	MemTotalGiB float64 `json:"mem_total_gib,omitempty"`
}

// BenchmarkCPULoad summarises host CPU utilisation sampled during the GPU
// steady-state phase. High or unstable CPU load during a GPU benchmark may
// indicate a competing workload or a CPU-bound driver bottleneck.
type BenchmarkCPULoad struct {
	AvgPct  float64 `json:"avg_pct"`
	MaxPct  float64 `json:"max_pct"`
	P95Pct  float64 `json:"p95_pct"`
	Samples int     `json:"samples"`
	// Status is "ok", "high", or "unstable".
	Status string `json:"status"`
	Note   string `json:"note,omitempty"`
}

const (
	NvidiaBenchmarkProfileStandard  = "standard"
	NvidiaBenchmarkProfileStability = "stability"
	NvidiaBenchmarkProfileOvernight = "overnight"
)

type NvidiaBenchmarkOptions struct {
	Profile           string
	SizeMB            int
	GPUIndices        []int
	ExcludeGPUIndices []int
	RunNCCL           bool
	ParallelGPUs      bool // run all selected GPUs simultaneously instead of sequentially
}


type NvidiaBenchmarkResult struct {
	BenchmarkVersion   string                       `json:"benchmark_version"`
	GeneratedAt        time.Time                    `json:"generated_at"`
	Hostname           string                       `json:"hostname,omitempty"`
	ServerModel        string                       `json:"server_model,omitempty"`
	BenchmarkProfile   string                       `json:"benchmark_profile"`
	ParallelGPUs       bool                         `json:"parallel_gpus,omitempty"`
	OverallStatus      string                       `json:"overall_status"`
	SelectedGPUIndices []int                        `json:"selected_gpu_indices"`
	Findings           []string                     `json:"findings,omitempty"`
	Warnings           []string                     `json:"warnings,omitempty"`
	Normalization      BenchmarkNormalization       `json:"normalization"`
	HostConfig         *BenchmarkHostConfig         `json:"host_config,omitempty"`
	CPULoad            *BenchmarkCPULoad            `json:"cpu_load,omitempty"`
	GPUs               []BenchmarkGPUResult         `json:"gpus"`
	Interconnect       *BenchmarkInterconnectResult `json:"interconnect,omitempty"`
	ServerPower        *BenchmarkServerPower        `json:"server_power,omitempty"`
}

type BenchmarkNormalization struct {
	Status string                      `json:"status"`
	Notes  []string                    `json:"notes,omitempty"`
	GPUs   []BenchmarkNormalizationGPU `json:"gpus,omitempty"`
}

type BenchmarkNormalizationGPU struct {
	Index                 int      `json:"index"`
	PersistenceMode       string   `json:"persistence_mode,omitempty"`
	GPUClockLockMHz       float64  `json:"gpu_clock_lock_mhz,omitempty"`
	GPUClockLockStatus    string   `json:"gpu_clock_lock_status,omitempty"`
	MemoryClockLockMHz    float64  `json:"memory_clock_lock_mhz,omitempty"`
	MemoryClockLockStatus string   `json:"memory_clock_lock_status,omitempty"`
	Notes                 []string `json:"notes,omitempty"`
}

type BenchmarkGPUResult struct {
	Index                  int                        `json:"index"`
	UUID                   string                     `json:"uuid,omitempty"`
	Name                   string                     `json:"name,omitempty"`
	BusID                  string                     `json:"bus_id,omitempty"`
	VBIOS                  string                     `json:"vbios,omitempty"`
	ComputeCapability      string                     `json:"compute_capability,omitempty"`
	Backend                string                     `json:"backend,omitempty"`
	Status                 string                     `json:"status"`
	PowerLimitW            float64                    `json:"power_limit_w,omitempty"`
	MultiprocessorCount    int                        `json:"multiprocessor_count,omitempty"`
	DefaultPowerLimitW     float64                    `json:"default_power_limit_w,omitempty"`
	// CalibratedPeakPowerW is the p95 power measured during a short
	// dcgmi targeted_power calibration run before the main benchmark.
	// Used as the reference denominator for PowerSustainScore instead of
	// the hardware default limit, which bee-gpu-burn cannot reach.
	CalibratedPeakPowerW   float64                    `json:"calibrated_peak_power_w,omitempty"`
	MaxGraphicsClockMHz    float64                    `json:"max_graphics_clock_mhz,omitempty"`
	BaseGraphicsClockMHz   float64                    `json:"base_graphics_clock_mhz,omitempty"`
	MaxMemoryClockMHz      float64                    `json:"max_memory_clock_mhz,omitempty"`
	LockedGraphicsClockMHz float64                    `json:"locked_graphics_clock_mhz,omitempty"`
	LockedMemoryClockMHz   float64                    `json:"locked_memory_clock_mhz,omitempty"`
	Baseline               BenchmarkTelemetrySummary  `json:"baseline"`
	Steady                 BenchmarkTelemetrySummary  `json:"steady"`
	Cooldown               BenchmarkTelemetrySummary  `json:"cooldown"`
	Throttle               BenchmarkThrottleCounters  `json:"throttle_counters"`
	PrecisionResults       []BenchmarkPrecisionResult `json:"precision_results,omitempty"`
	Scores                 BenchmarkScorecard         `json:"scores"`
	DegradationReasons     []string                   `json:"degradation_reasons,omitempty"`
	Notes                  []string                   `json:"notes,omitempty"`
}

type BenchmarkTelemetrySummary struct {
	DurationSec         float64 `json:"duration_sec"`
	Samples             int     `json:"samples"`
	AvgTempC            float64 `json:"avg_temp_c"`
	P95TempC            float64 `json:"p95_temp_c"`
	AvgPowerW           float64 `json:"avg_power_w"`
	P95PowerW           float64 `json:"p95_power_w"`
	AvgGraphicsClockMHz float64 `json:"avg_graphics_clock_mhz"`
	P95GraphicsClockMHz float64 `json:"p95_graphics_clock_mhz"`
	AvgMemoryClockMHz   float64 `json:"avg_memory_clock_mhz"`
	P95MemoryClockMHz   float64 `json:"p95_memory_clock_mhz"`
	AvgUsagePct         float64 `json:"avg_usage_pct"`
	AvgMemUsagePct      float64 `json:"avg_mem_usage_pct"`
	ClockCVPct          float64 `json:"clock_cv_pct"`
	PowerCVPct          float64 `json:"power_cv_pct"`
	TempCVPct           float64 `json:"temp_cv_pct"`
	ClockDriftPct       float64 `json:"clock_drift_pct"`
}

type BenchmarkThrottleCounters struct {
	SWPowerCapUS           uint64 `json:"sw_power_cap_us"`
	SWThermalSlowdownUS    uint64 `json:"sw_thermal_slowdown_us"`
	SyncBoostUS            uint64 `json:"sync_boost_us"`
	HWThermalSlowdownUS    uint64 `json:"hw_thermal_slowdown_us"`
	HWPowerBrakeSlowdownUS uint64 `json:"hw_power_brake_slowdown_us"`
}

type BenchmarkPrecisionResult struct {
	Name          string  `json:"name"`
	Category      string  `json:"category"`
	Supported     bool    `json:"supported"`
	Lanes         int     `json:"lanes,omitempty"`
	M             uint64  `json:"m,omitempty"`
	N             uint64  `json:"n,omitempty"`
	K             uint64  `json:"k,omitempty"`
	Iterations    uint64  `json:"iterations,omitempty"`
	TeraOpsPerSec float64 `json:"teraops_per_sec,omitempty"`
	Notes         string  `json:"notes,omitempty"`
}

type BenchmarkScorecard struct {
	ComputeScore        float64 `json:"compute_score"`
	PowerSustainScore   float64 `json:"power_sustain_score"`
	ThermalSustainScore float64 `json:"thermal_sustain_score"`
	StabilityScore      float64 `json:"stability_score"`
	InterconnectScore   float64 `json:"interconnect_score"`
	CompositeScore      float64 `json:"composite_score"`
	// TOPSPerSMPerGHz is compute efficiency independent of clock speed and SM count.
	// Comparable across throttle levels and GPU generations. Low value at normal
	// clocks indicates silicon degradation.
	TOPSPerSMPerGHz float64 `json:"tops_per_sm_per_ghz,omitempty"`
}

// BenchmarkServerPower captures server-side power via IPMI alongside GPU-reported
// power. The reporting_ratio (delta / gpu_reported_sum) near 1.0 means GPU power
// telemetry is accurate; a ratio well below 1.0 (e.g. 0.5) means the GPU is
// over-reporting its power consumption.
type BenchmarkServerPower struct {
	Available       bool     `json:"available"`
	IdleW           float64  `json:"idle_w,omitempty"`
	LoadedW         float64  `json:"loaded_w,omitempty"`
	DeltaW          float64  `json:"delta_w,omitempty"`
	GPUReportedSumW float64  `json:"gpu_reported_sum_w,omitempty"`
	ReportingRatio  float64  `json:"reporting_ratio,omitempty"`
	Notes           []string `json:"notes,omitempty"`
}

type BenchmarkInterconnectResult struct {
	Status             string   `json:"status"`
	Attempted          bool     `json:"attempted"`
	Supported          bool     `json:"supported"`
	SelectedGPUIndices []int    `json:"selected_gpu_indices,omitempty"`
	AvgAlgBWGBps       float64  `json:"avg_algbw_gbps,omitempty"`
	MaxAlgBWGBps       float64  `json:"max_algbw_gbps,omitempty"`
	AvgBusBWGBps       float64  `json:"avg_busbw_gbps,omitempty"`
	MaxBusBWGBps       float64  `json:"max_busbw_gbps,omitempty"`
	Notes              []string `json:"notes,omitempty"`
}
