package models

import "time"

const (
	SourceTypeArchive = "archive"
	SourceTypeAPI     = "api"
)

// AnalysisResult contains all parsed data from an archive
type AnalysisResult struct {
	Filename       string          `json:"filename"`
	SourceType     string          `json:"source_type,omitempty"`     // archive | api
	Protocol       string          `json:"protocol,omitempty"`        // redfish | ipmi
	TargetHost     string          `json:"target_host,omitempty"`     // BMC host for live collect
	SourceTimezone string          `json:"source_timezone,omitempty"` // Source timezone/offset used during collection (e.g. +08:00)
	CollectedAt              time.Time       `json:"collected_at,omitempty"`               // Collection/upload timestamp
	InventoryLastModifiedAt  time.Time       `json:"inventory_last_modified_at,omitempty"` // Redfish inventory last modified (InventoryData/Status)
	RawPayloads    map[string]any  `json:"raw_payloads,omitempty"`    // Additional source payloads (e.g. Redfish tree)
	Events         []Event         `json:"events"`
	FRU            []FRUInfo       `json:"fru"`
	Sensors        []SensorReading `json:"sensors"`
	Hardware       *HardwareConfig `json:"hardware"`
}

// Event represents a single log event
type Event struct {
	ID          string    `json:"id"`
	Timestamp   time.Time `json:"timestamp"`
	Source      string    `json:"source"`
	SensorType  string    `json:"sensor_type"`
	SensorName  string    `json:"sensor_name"`
	EventType   string    `json:"event_type"`
	Severity    Severity  `json:"severity"`
	Description string    `json:"description"`
	RawData     string    `json:"raw_data,omitempty"`
}

// Severity represents event severity level
type Severity string

const (
	SeverityCritical Severity = "critical"
	SeverityWarning  Severity = "warning"
	SeverityInfo     Severity = "info"
)

// StatusAtCollection captures component status at a specific timestamp.
type StatusAtCollection struct {
	Status string    `json:"status"`
	At     time.Time `json:"at"`
}

// StatusHistoryEntry represents a status transition point.
type StatusHistoryEntry struct {
	Status    string    `json:"status"`
	ChangedAt time.Time `json:"changed_at"`
	Details   string    `json:"details,omitempty"`
}

// SensorReading represents a single sensor reading
type SensorReading struct {
	Name     string  `json:"name"`
	Type     string  `json:"type"`
	Value    float64 `json:"value,omitempty"`
	Unit     string  `json:"unit,omitempty"`
	RawValue string  `json:"raw_value,omitempty"`
	Status   string  `json:"status"`
}

// FRUInfo represents Field Replaceable Unit information
type FRUInfo struct {
	DeviceID     string `json:"device_id,omitempty"`
	Description  string `json:"description"`
	ChassisType  string `json:"chassis_type,omitempty"`
	Manufacturer string `json:"manufacturer,omitempty"`
	ProductName  string `json:"product_name,omitempty"`
	SerialNumber string `json:"serial_number,omitempty"`
	PartNumber   string `json:"part_number,omitempty"`
	Version      string `json:"version,omitempty"`
	MfgDate      string `json:"mfg_date,omitempty"`
	AssetTag     string `json:"asset_tag,omitempty"`
}

// HardwareConfig represents server hardware configuration
type HardwareConfig struct {
	Firmware        []FirmwareInfo   `json:"firmware,omitempty"`
	BoardInfo       BoardInfo        `json:"board,omitempty"`
	Devices         []HardwareDevice `json:"devices,omitempty"`
	CPUs            []CPU            `json:"cpus,omitempty"`
	Memory          []MemoryDIMM     `json:"memory,omitempty"`
	Storage         []Storage        `json:"storage,omitempty"`
	Volumes         []StorageVolume  `json:"volumes,omitempty"`
	PCIeDevices     []PCIeDevice     `json:"pcie_devices,omitempty"`
	GPUs            []GPU            `json:"gpus,omitempty"`
	NetworkCards    []NIC            `json:"network_cards,omitempty"`
	NetworkAdapters []NetworkAdapter `json:"network_adapters,omitempty"`
	PowerSupply     []PSU            `json:"power_supplies,omitempty"`
}

const (
	DeviceKindBoard   = "board"
	DeviceKindCPU     = "cpu"
	DeviceKindMemory  = "memory"
	DeviceKindStorage = "storage"
	DeviceKindPCIe    = "pcie"
	DeviceKindGPU     = "gpu"
	DeviceKindNetwork = "network"
	DeviceKindPSU     = "psu"
)

// HardwareDevice is canonical device inventory used across UI and exports.
type HardwareDevice struct {
	ID                    string   `json:"id"`
	Kind                  string   `json:"kind"`
	Source                string   `json:"source,omitempty"`
	Slot                  string   `json:"slot,omitempty"`
	Location              string   `json:"location,omitempty"`
	BDF                   string   `json:"bdf,omitempty"`
	DeviceClass           string   `json:"device_class,omitempty"`
	VendorID              int      `json:"vendor_id,omitempty"`
	DeviceID              int      `json:"device_id,omitempty"`
	Model                 string   `json:"model,omitempty"`
	PartNumber            string   `json:"part_number,omitempty"`
	Manufacturer          string   `json:"manufacturer,omitempty"`
	SerialNumber          string   `json:"serial_number,omitempty"`
	Firmware              string   `json:"firmware,omitempty"`
	Type                  string   `json:"type,omitempty"`
	Interface             string   `json:"interface,omitempty"`
	Present               *bool    `json:"present,omitempty"`
	SizeMB                int      `json:"size_mb,omitempty"`
	SizeGB                int      `json:"size_gb,omitempty"`
	Cores                 int      `json:"cores,omitempty"`
	Threads               int      `json:"threads,omitempty"`
	FrequencyMHz          int      `json:"frequency_mhz,omitempty"`
	MaxFreqMHz            int      `json:"max_frequency_mhz,omitempty"`
	PortCount             int      `json:"port_count,omitempty"`
	PortType              string   `json:"port_type,omitempty"`
	MACAddresses          []string `json:"mac_addresses,omitempty"`
	LinkWidth             int      `json:"link_width,omitempty"`
	LinkSpeed             string   `json:"link_speed,omitempty"`
	MaxLinkWidth          int      `json:"max_link_width,omitempty"`
	MaxLinkSpeed          string   `json:"max_link_speed,omitempty"`
	WattageW              int      `json:"wattage_w,omitempty"`
	InputType             string   `json:"input_type,omitempty"`
	InputPowerW           int      `json:"input_power_w,omitempty"`
	OutputPowerW          int      `json:"output_power_w,omitempty"`
	InputVoltage          float64  `json:"input_voltage,omitempty"`
	TemperatureC          int      `json:"temperature_c,omitempty"`
	RemainingEndurancePct *int     `json:"remaining_endurance_pct,omitempty"` // 0-100 %; nil = not reported
	NUMANode              int      `json:"numa_node,omitempty"`               // 0 = not reported/N/A
	Status                string   `json:"status,omitempty"`

	StatusCheckedAt  *time.Time           `json:"status_checked_at,omitempty"`
	StatusChangedAt  *time.Time           `json:"status_changed_at,omitempty"`
	StatusAtCollect  *StatusAtCollection  `json:"status_at_collection,omitempty"`
	StatusHistory    []StatusHistoryEntry `json:"status_history,omitempty"`
	ErrorDescription string               `json:"error_description,omitempty"`

	Details map[string]any `json:"details,omitempty"`
}

// FirmwareInfo represents firmware version information
type FirmwareInfo struct {
	DeviceName  string `json:"device_name"`
	Description string `json:"description,omitempty"`
	Version     string `json:"version"`
	BuildTime   string `json:"build_time,omitempty"`
}

// BoardInfo represents motherboard/system information
type BoardInfo struct {
	Manufacturer  string `json:"manufacturer,omitempty"`
	ProductName   string `json:"product_name,omitempty"`
	Description   string `json:"description,omitempty"`
	SerialNumber  string `json:"serial_number,omitempty"`
	PartNumber    string `json:"part_number,omitempty"`
	Version       string `json:"version,omitempty"`
	UUID          string `json:"uuid,omitempty"`
	BMCMACAddress string `json:"bmc_mac_address,omitempty"`
}

// CPU represents processor information
type CPU struct {
	Socket       int    `json:"socket"`
	Model        string `json:"model"`
	Description  string `json:"description,omitempty"`
	Cores        int    `json:"cores"`
	Threads      int    `json:"threads"`
	FrequencyMHz int    `json:"frequency_mhz"`
	MaxFreqMHz   int    `json:"max_frequency_mhz,omitempty"`
	L1CacheKB    int    `json:"l1_cache_kb,omitempty"`
	L2CacheKB    int    `json:"l2_cache_kb,omitempty"`
	L3CacheKB    int    `json:"l3_cache_kb,omitempty"`
	TDP          int    `json:"tdp_w,omitempty"`
	PPIN         string `json:"ppin,omitempty"`
	SerialNumber string `json:"serial_number,omitempty"`
	Status       string `json:"status,omitempty"`

	StatusCheckedAt  *time.Time           `json:"status_checked_at,omitempty"`
	StatusChangedAt  *time.Time           `json:"status_changed_at,omitempty"`
	StatusAtCollect  *StatusAtCollection  `json:"status_at_collection,omitempty"`
	StatusHistory    []StatusHistoryEntry `json:"status_history,omitempty"`
	ErrorDescription string               `json:"error_description,omitempty"`
	Details          map[string]any       `json:"details,omitempty"`
}

// MemoryDIMM represents a memory module
type MemoryDIMM struct {
	Slot            string `json:"slot"`
	Location        string `json:"location"`
	Description     string `json:"description,omitempty"`
	Present         bool   `json:"present"`
	SizeMB          int    `json:"size_mb"`
	Type            string `json:"type"`
	Technology      string `json:"technology,omitempty"`
	MaxSpeedMHz     int    `json:"max_speed_mhz"`
	CurrentSpeedMHz int    `json:"current_speed_mhz"`
	Manufacturer    string `json:"manufacturer,omitempty"`
	SerialNumber    string `json:"serial_number,omitempty"`
	PartNumber      string `json:"part_number,omitempty"`
	Status          string `json:"status,omitempty"`
	Ranks           int    `json:"ranks,omitempty"`

	StatusCheckedAt  *time.Time           `json:"status_checked_at,omitempty"`
	StatusChangedAt  *time.Time           `json:"status_changed_at,omitempty"`
	StatusAtCollect  *StatusAtCollection  `json:"status_at_collection,omitempty"`
	StatusHistory    []StatusHistoryEntry `json:"status_history,omitempty"`
	ErrorDescription string               `json:"error_description,omitempty"`
	Details          map[string]any       `json:"details,omitempty"`
}

// Storage represents a storage device
type Storage struct {
	Slot                  string         `json:"slot"`
	Type                  string         `json:"type"`
	Model                 string         `json:"model"`
	Description           string         `json:"description,omitempty"`
	SizeGB                int            `json:"size_gb"`
	SerialNumber          string         `json:"serial_number,omitempty"`
	Manufacturer          string         `json:"manufacturer,omitempty"`
	Firmware              string         `json:"firmware,omitempty"`
	Interface             string         `json:"interface,omitempty"`
	Present               bool           `json:"present"`
	Location              string         `json:"location,omitempty"` // Front/Rear
	BackplaneID           int            `json:"backplane_id,omitempty"`
	RemainingEndurancePct *int           `json:"remaining_endurance_pct,omitempty"` // 0-100 %; nil = not reported
	Status                string         `json:"status,omitempty"`
	Details               map[string]any `json:"details,omitempty"`

	StatusCheckedAt  *time.Time           `json:"status_checked_at,omitempty"`
	StatusChangedAt  *time.Time           `json:"status_changed_at,omitempty"`
	StatusAtCollect  *StatusAtCollection  `json:"status_at_collection,omitempty"`
	StatusHistory    []StatusHistoryEntry `json:"status_history,omitempty"`
	ErrorDescription string               `json:"error_description,omitempty"`
}

// StorageVolume represents a logical storage volume (RAID/VROC/etc.).
type StorageVolume struct {
	ID            string `json:"id,omitempty"`
	Name          string `json:"name,omitempty"`
	Controller    string `json:"controller,omitempty"`
	RAIDLevel     string `json:"raid_level,omitempty"`
	SizeGB        int    `json:"size_gb,omitempty"`
	CapacityBytes int64  `json:"capacity_bytes,omitempty"`
	Status        string `json:"status,omitempty"`
	Bootable      bool   `json:"bootable,omitempty"`
	Encrypted     bool   `json:"encrypted,omitempty"`
}

// PCIeDevice represents a PCIe device
type PCIeDevice struct {
	Slot         string   `json:"slot"`
	Description  string   `json:"description,omitempty"`
	VendorID     int      `json:"vendor_id"`
	DeviceID     int      `json:"device_id"`
	BDF          string   `json:"bdf"`
	DeviceClass  string   `json:"device_class"`
	Manufacturer string   `json:"manufacturer,omitempty"`
	LinkWidth    int      `json:"link_width"`
	LinkSpeed    string   `json:"link_speed"`
	MaxLinkWidth int      `json:"max_link_width"`
	MaxLinkSpeed string   `json:"max_link_speed"`
	PartNumber   string   `json:"part_number,omitempty"`
	SerialNumber string   `json:"serial_number,omitempty"`
	MACAddresses []string `json:"mac_addresses,omitempty"`
	NUMANode     int      `json:"numa_node,omitempty"` // 0 = not reported/N/A
	Status       string   `json:"status,omitempty"`

	StatusCheckedAt  *time.Time           `json:"status_checked_at,omitempty"`
	StatusChangedAt  *time.Time           `json:"status_changed_at,omitempty"`
	StatusAtCollect  *StatusAtCollection  `json:"status_at_collection,omitempty"`
	StatusHistory    []StatusHistoryEntry `json:"status_history,omitempty"`
	ErrorDescription string               `json:"error_description,omitempty"`
	Details          map[string]any       `json:"details,omitempty"`
}

// NIC represents a network interface card
type NIC struct {
	Name         string `json:"name"`
	Model        string `json:"model"`
	Description  string `json:"description,omitempty"`
	MACAddress   string `json:"mac_address"`
	SpeedMbps    int    `json:"speed_mbps,omitempty"`
	SerialNumber string `json:"serial_number,omitempty"`
}

// PSU represents a power supply unit
type PSU struct {
	Slot          string         `json:"slot"`
	Present       bool           `json:"present"`
	Model         string         `json:"model"`
	Description   string         `json:"description,omitempty"`
	Vendor        string         `json:"vendor,omitempty"`
	WattageW      int            `json:"wattage_w,omitempty"`
	SerialNumber  string         `json:"serial_number,omitempty"`
	PartNumber    string         `json:"part_number,omitempty"`
	Firmware      string         `json:"firmware,omitempty"`
	Status        string         `json:"status,omitempty"`
	InputType     string         `json:"input_type,omitempty"`
	InputPowerW   int            `json:"input_power_w,omitempty"`
	OutputPowerW  int            `json:"output_power_w,omitempty"`
	InputVoltage  float64        `json:"input_voltage,omitempty"`
	OutputVoltage float64        `json:"output_voltage,omitempty"`
	TemperatureC  int            `json:"temperature_c,omitempty"`
	Details       map[string]any `json:"details,omitempty"`

	StatusCheckedAt  *time.Time           `json:"status_checked_at,omitempty"`
	StatusChangedAt  *time.Time           `json:"status_changed_at,omitempty"`
	StatusAtCollect  *StatusAtCollection  `json:"status_at_collection,omitempty"`
	StatusHistory    []StatusHistoryEntry `json:"status_history,omitempty"`
	ErrorDescription string               `json:"error_description,omitempty"`
}

// GPU represents a graphics processing unit
type GPU struct {
	Slot             string `json:"slot"`
	Location         string `json:"location,omitempty"`
	Model            string `json:"model"`
	Description      string `json:"description,omitempty"`
	Manufacturer     string `json:"manufacturer,omitempty"`
	VendorID         int    `json:"vendor_id,omitempty"`
	DeviceID         int    `json:"device_id,omitempty"`
	BDF              string `json:"bdf,omitempty"`
	UUID             string `json:"uuid,omitempty"`
	SerialNumber     string `json:"serial_number,omitempty"`
	PartNumber       string `json:"part_number,omitempty"`
	Firmware         string `json:"firmware,omitempty"`
	VideoBIOS        string `json:"video_bios,omitempty"`
	IRQ              int    `json:"irq,omitempty"`
	BusType          string `json:"bus_type,omitempty"`
	DMASize          string `json:"dma_size,omitempty"`
	DMAMask          string `json:"dma_mask,omitempty"`
	DeviceMinor      int    `json:"device_minor,omitempty"`
	Temperature      int    `json:"temperature,omitempty"`     // GPU core temp
	MemTemperature   int    `json:"mem_temperature,omitempty"` // GPU memory temp
	Power            int    `json:"power,omitempty"`           // Current power draw (W)
	MaxPower         int    `json:"max_power,omitempty"`       // TDP (W)
	ClockSpeed       int    `json:"clock_speed,omitempty"`     // Operating speed MHz
	MaxLinkWidth     int    `json:"max_link_width,omitempty"`
	MaxLinkSpeed     string `json:"max_link_speed,omitempty"`
	CurrentLinkWidth int    `json:"current_link_width,omitempty"`
	CurrentLinkSpeed string `json:"current_link_speed,omitempty"`
	Status           string `json:"status,omitempty"`

	StatusCheckedAt  *time.Time           `json:"status_checked_at,omitempty"`
	StatusChangedAt  *time.Time           `json:"status_changed_at,omitempty"`
	StatusAtCollect  *StatusAtCollection  `json:"status_at_collection,omitempty"`
	StatusHistory    []StatusHistoryEntry `json:"status_history,omitempty"`
	ErrorDescription string               `json:"error_description,omitempty"`
	Details          map[string]any       `json:"details,omitempty"`
}

// NetworkAdapter represents a network adapter with detailed info
type NetworkAdapter struct {
	Slot         string   `json:"slot"`
	Location     string   `json:"location"`
	Present      bool     `json:"present"`
	BDF          string   `json:"bdf,omitempty"`
	Model        string   `json:"model"`
	Description  string   `json:"description,omitempty"`
	Vendor       string   `json:"vendor,omitempty"`
	VendorID     int      `json:"vendor_id,omitempty"`
	DeviceID     int      `json:"device_id,omitempty"`
	SerialNumber string   `json:"serial_number,omitempty"`
	PartNumber   string   `json:"part_number,omitempty"`
	Firmware     string   `json:"firmware,omitempty"`
	PortCount    int      `json:"port_count,omitempty"`
	PortType     string   `json:"port_type,omitempty"`
	MACAddresses []string `json:"mac_addresses,omitempty"`
	LinkWidth    int      `json:"link_width,omitempty"`
	LinkSpeed    string   `json:"link_speed,omitempty"`
	MaxLinkWidth int      `json:"max_link_width,omitempty"`
	MaxLinkSpeed string   `json:"max_link_speed,omitempty"`
	NUMANode     int      `json:"numa_node,omitempty"` // 0 = not reported/N/A
	Status       string   `json:"status,omitempty"`

	StatusCheckedAt  *time.Time           `json:"status_checked_at,omitempty"`
	StatusChangedAt  *time.Time           `json:"status_changed_at,omitempty"`
	StatusAtCollect  *StatusAtCollection  `json:"status_at_collection,omitempty"`
	StatusHistory    []StatusHistoryEntry `json:"status_history,omitempty"`
	ErrorDescription string               `json:"error_description,omitempty"`
	Details          map[string]any       `json:"details,omitempty"`
}
