package sep

import "encoding/json"

// Total resource information
type Total struct {
	// Capacity limit
	CapacityLimit uint64 `json:"capacity_limit"`

	// Disk count
	DiskCount uint64 `json:"disk_count"`

	// Disk usage
	DiskUsage uint64 `json:"disk_usage"`

	// Snapshot count
	SnapshotCount uint64 `json:"snapshot_count"`

	// Snapshot usage
	SnapshotUsage uint64 `json:"snapshot_usage"`

	// Usage
	Usage uint64 `json:"usage"`

	// Usage limit
	UsageLimit uint64 `json:"usage_limit"`
}

type ByPool struct {

	// Disk count
	DiskCount uint64 `json:"disk_count"`

	// Disk usage
	DiskUsage uint64 `json:"disk_usage"`

	// Snapshot count
	SnapshotCount uint64 `json:"snapshot_count"`

	// Snapshot usage
	SnapshotUsage uint64 `json:"snapshot_usage"`

	// Usage
	Usage uint64 `json:"usage"`

	// Usage limit
	UsageLimit uint64 `json:"usage_limit"`
}

// List of Resource groups
type ListConsumption struct {
	// Data
	Data []RecordConsumption `json:"data"`

	// Enrtry count
	EntryCount uint64 `json:"entryCount"`
}

// Main information about consumption
type RecordConsumption struct {
	// ID
	ID uint64 `json:"id"`

	// Name
	Name string `json:"name"`
	// By pool
	ByPool map[string]ByPool `json:"byPool"`

	// Total resource information
	Total Total `json:"total"`

	// Type
	Type string `json:"type"`

	// Consumed by
	ConsumedBy []uint64 `json:"consumedBy"`
}

// Main information about URI
type ItemURI struct {
	// IP
	IP string `json:"ip"`

	// Port
	Port uint64 `json:"port"`
}

// List URIs
type ListURIs []ItemURI

// Detailed information about SEP pool
type RecordPool struct {
	// List access account IDs
	AccessAccountIDs []uint64 `json:"accessAccountIds"`

	// List access resource group IDs
	AccessResGroupIDs []uint64 `json:"accessResGroupIds"`

	// Name
	Name string `json:"name"`

	//  Page cache ratio
	PageCacheRatio uint64 `json:"pagecache_ratio"`

	// Reference ID
	ReferenceID string `json:"referenceId"`

	// List types
	Types []string `json:"types"`

	// List URIs
	URIs ListURIs `json:"uris"`

	// Usage Limit
	UsageLimit uint64 `json:"usage_limit"`
}

// SEP config
type SEPConfig map[string]interface{}

// Detailed information about SEP
type RecordSEP struct {
	// Config
	Config SEPConfig `json:"config"`

	// Consumed by
	ConsumedBy []uint64 `json:"consumedBy"`

	// Description
	Description string `json:"desc"`

	// Grid ID
	GID uint64 `json:"gid"`

	// GUID
	GUID uint64 `json:"guid"`

	// ID
	ID uint64 `json:"id"`

	// Milestones
	Milestones uint64 `json:"milestones"`

	// MultipathNum
	MultipathNum uint64 `json:"multipathNum"`

	// Name
	Name string `json:"name"`

	// Object status
	ObjStatus string `json:"objStatus"`

	// Provided by
	ProvidedBy []uint64 `json:"providedBy"`

	// Shared with
	SharedWith []uint64 `json:"sharedWith"`

	// Tech status
	TechStatus string `json:"techStatus"`

	// Type
	Type string `json:"type"`
}

// List SEPs
type ListSEP struct {
	// Data
	Data []RecordSEP `json:"data"`

	// Entry count
	EntryCount uint64 `json:"entryCount"`
}

type Pool struct {
	// Pool name
	Name string `json:"name"`

	// Pool types
	Types []string `json:"types"`

	// System
	System bool `json:"system"`
}

type SEPData struct {
	// SEP ID
	SEPID uint64 `json:"sepId"`

	// SEP name
	SEPName string `json:"sepName"`

	// Sep type
	SEPType string `json:"sepType"`

	// Pools
	Pools []Pool `json:"pools"`
}

type ListAvailableSEP struct {
	// Entry count
	EntryCount uint64 `json:"entryCount"`

	// Data
	Data []SEPData `json:"data"`
}

// Disk clean settings
type DiskCleanSettings struct {
	// Block size
	BlockSize string `json:"blocksize"`

	// Write bytes per second
	WBPS uint64 `json:"wbps"`

	// Write I/O operations per second
	WIOPS uint64 `json:"wiops"`
}

// Pool configuration
type PoolConfig struct {
	// Disk clean
	DiskClean *string `json:"disk_clean"`

	// Disk clean settings
	DiskCleanSettings DiskCleanSettings `json:"disk_clean_settings"`

	// Pool name
	Name string `json:"name"`

	// Usage limit
	UsageLimit uint64 `json:"usage_limit"`

	// Additional properties
	AdditionalProperties map[string]interface{} `json:"-"`
}

func (p *PoolConfig) UnmarshalJSON(data []byte) error {
	type tmpAlias PoolConfig
	if err := json.Unmarshal(data, (*tmpAlias)(p)); err != nil {
		return err
	}

	all := make(map[string]interface{})
	if err := json.Unmarshal(data, &all); err != nil {
		return err
	}

	delete(all, "disk_clean")
	delete(all, "disk_clean_settings")
	delete(all, "name")
	delete(all, "usage_limit")

	if len(all) > 0 {
		p.AdditionalProperties = all
	}

	return nil
}

// Sep configuration information
type RecordConfigFieldEdit struct {
	// Format
	Format string `json:"format"`

	// Pools
	Pools []PoolConfig `json:"pools"`

	// Protocol
	Protocol string `json:"protocol"`

	// Additional properties
	AdditionalProperties map[string]interface{} `json:"-"`
}

func (r *RecordConfigFieldEdit) UnmarshalJSON(data []byte) error {
	type tmpAlias RecordConfigFieldEdit
	if err := json.Unmarshal(data, (*tmpAlias)(r)); err != nil {
		return err
	}

	all := make(map[string]interface{})
	if err := json.Unmarshal(data, &all); err != nil {
		return err
	}

	delete(all, "format")
	delete(all, "pools")
	delete(all, "protocol")

	if len(all) > 0 {
		r.AdditionalProperties = all
	}

	return nil
}
