// Copyright The Monogon Project Authors.
// SPDX-License-Identifier: Apache-2.0

package nvme

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"math/big"
)

// Figure 109
type identifyData struct {
	// Controller Capabilities and Features
	PCIVendorID                 uint16
	PCISubsystemVendorID        uint16
	SerialNumber                [20]byte
	ModelNumber                 [40]byte
	FirmwareRevision            [8]byte
	RecommendedArbitrationBurst uint8
	IEEEOUI                     [3]byte
	CMIC                        uint8
	MaximumDataTransferSize     uint8
	ControllerID                uint16
	Version                     uint32
	RuntimeD3ResumeLatency      uint32
	RuntimeD3EntryLatency       uint32
	OAES                        uint32
	CTRATT                      uint32
	_                           [12]byte
	FRUGUID                     [16]byte
	_                           [128]byte
	// Admin Command Set Attributes & Optional Controller Capabilities
	OACS                                uint16
	AbortCommandLimit                   uint8
	AsynchronousEventRequestLimit       uint8
	FRMW                                uint8
	LPA                                 uint8
	ErrorLogPageEntries                 uint8
	NumberOfPowerStatesSupport          uint8
	AdminVendorSpecificCmdConfig        uint8
	AutonomousPowerStateTransitionAttrs uint8
	WarningCompositeTempThreshold       uint16
	CriticalCompositeTempThreshold      uint16
	MaximumTimeForFirmwareActivation    uint16
	HostMemoryBufferPreferredSize       uint32
	HostMemoryBufferMinimumSize         uint32
	TotalNVMCapacity                    uint128le
	UnallocatedNVMCapacity              uint128le
	ReplyProtectedMemoryBlockSupport    uint32
	ExtendedDeviceSelfTestTime          uint16
	DeviceSelfTestOptions               uint8
	FirmwareUpdateGranularity           uint8
	KeepAliveSupport                    uint16
	HostControlledThermalMgmtAttrs      uint16
	MinimumThermalMgmntTemp             uint16
	MaximumThermalMgmntTemp             uint16
	SanitizeCapabilities                uint32
	_                                   [180]byte
	// NVM Command Set Attributes
	SubmissionQueueEntrySize       uint8
	CompletionQueueEntrySize       uint8
	MaximumOutstandingCommands     uint16
	NumberOfNamespaces             uint32
	OptionalNVMCommandSupport      uint16
	FusedOperationSupport          uint16
	FormatNVMAttributes            uint8
	VolatileWriteCache             uint8
	AtomicWriteUnitNormal          uint16
	AtomicWriteUnitPowerFail       uint16
	NVMVendorSepcificCommandConfig uint8
	AtomicCompareAndWriteUnit      uint16
	_                              [2]byte
	SGLSupport                     uint32
	_                              [228]byte
	NVMSubsystemNVMeQualifiedName  [256]byte
	_                              [1024]byte
	// Power State Descriptors
	PowerStateDescriptors [32][32]byte
}

// IdentifyData contains various identifying information about a NVMe
// controller. Because the actual data structure is very large, currently not
// all fields are exposed as properly-typed individual fields. If you need
// a new field, please add it to this structure.
type IdentifyData struct {
	// PCIVendorID contains the company vendor identifier assigned by the PCI
	// SIG.
	PCIVendorID uint16
	// PCISubsystemVendorID contains the company vendor identifier that is
	// assigned by the PCI SIG for the subsystem.
	PCISubsystemVendorID uint16
	// SerialNumber contains the serial number for the NVM subsystem that is
	// assigned by the vendor.
	SerialNumber string
	// ModelNumber contains the model number for the NVM subsystem that is
	// assigned by the vendor.
	ModelNumber string
	// FirmwareRevision contains the currently active firmware revision for the
	// NVM subsystem.
	FirmwareRevision string
	// IEEEOUI contains the Organization Unique Identifier for the controller
	// vendor as assigned by the IEEE.
	IEEEOUI [3]byte

	// IsPCIVirtualFunction indicates if the controller is a virtual controller
	// as part of a PCI virtual function.
	IsPCIVirtualFunction bool

	// SpecVersionMajor/Minor contain the version of the NVMe specification the
	// controller supports. Only mandatory from spec version 1.2 onwards.
	SpecVersionMajor uint16
	SpecVersionMinor uint8

	// FRUGloballyUniqueIdentifier contains a 128-bit value that is globally
	// unique for a given Field Replaceable Unit (FRU). Contains all-zeroes if
	// unavailable.
	FRUGloballyUniqueIdentifier [16]byte
	// VirtualizationManagementSupported indicates if the controller
	// supports the Virtualization Management command.
	VirtualizationManagementSupported bool
	// NVMeMISupported indicates if the controller supports the NVMe-MI
	// Send and Receive commands.
	NVMeMISupported bool
	// DirectivesSupported indicates if the controller supports the
	// Directive Send and Receive commands.
	DirectivesSupported bool
	// SelfTestSupported indicates if the controller supports the Device Self-
	// test command.
	SelfTestSupported bool
	// NamespaceManagementSupported indicates if the controller supports the
	// Namespace Management and Attachment commands.
	NamespaceManagementSupported bool
	// FirmwareUpdateSupported indicates if the controller supports the
	// Firmware Commit and Image Download commands.
	FirmwareUpdateSupported bool
	// FormattingSupported indicates if the controller supports the Format
	// command.
	FormattingSupported bool
	// SecuritySupported indicates if the controller supports the Security Send
	// and Receive commands.
	SecuritySupported bool

	// TotalNVMCapacity contains the total NVM capacity in bytes in the NVM
	// subsystem. This can be 0 on devices without NamespaceManagementSupported.
	TotalNVMCapacity *big.Int
	// UnallocatedNVMCapacity contains the unallocated NVM capacity in bytes in
	// the NVM subsystem. This can be 0 on devices without
	// NamespaceManagementSupported.
	UnallocatedNVMCapacity *big.Int

	// MaximumNumberOfNamespace defines the maximum number of namespaces
	// supported by the controller.
	MaximumNumberOfNamespaces uint32
}

func (d *Device) Identify() (*IdentifyData, error) {
	var resp [4096]byte

	if err := d.RawCommand(&Command{
		Opcode: 0x06,
		Data:   resp[:],
		CDW10:  1,
	}); err != nil {
		return nil, fmt.Errorf("Identify command failed: %w", err)
	}
	var raw identifyData
	binary.Read(bytes.NewReader(resp[:]), binary.LittleEndian, &raw)

	var res IdentifyData
	res.PCIVendorID = raw.PCIVendorID
	res.PCISubsystemVendorID = raw.PCISubsystemVendorID
	res.SerialNumber = string(bytes.TrimRight(raw.SerialNumber[:], " "))
	res.ModelNumber = string(bytes.TrimRight(raw.ModelNumber[:], " "))
	res.FirmwareRevision = string(bytes.TrimRight(raw.FirmwareRevision[:], " "))
	// OUIs are traditionally big-endian, but NVMe exposes them in little-endian
	res.IEEEOUI[0], res.IEEEOUI[1], res.IEEEOUI[2] = raw.IEEEOUI[2], raw.IEEEOUI[1], raw.IEEEOUI[0]
	res.IsPCIVirtualFunction = raw.CMIC&(1<<2) != 0
	res.SpecVersionMajor = uint16(raw.Version >> 16)
	res.SpecVersionMinor = uint8((raw.Version >> 8) & 0xFF)
	res.FRUGloballyUniqueIdentifier = raw.FRUGUID
	res.VirtualizationManagementSupported = raw.OACS&(1<<7) != 0
	res.NVMeMISupported = raw.OACS&(1<<6) != 0
	res.DirectivesSupported = raw.OACS&(1<<5) != 0
	res.SelfTestSupported = raw.OACS&(1<<4) != 0
	res.NamespaceManagementSupported = raw.OACS&(1<<3) != 0
	res.FirmwareUpdateSupported = raw.OACS&(1<<2) != 0
	res.FormattingSupported = raw.OACS&(1<<1) != 0
	res.SecuritySupported = raw.OACS&(1<<0) != 0

	res.TotalNVMCapacity = raw.TotalNVMCapacity.BigInt()
	res.UnallocatedNVMCapacity = raw.UnallocatedNVMCapacity.BigInt()
	res.MaximumNumberOfNamespaces = raw.NumberOfNamespaces
	return &res, nil
}
