package define

import (
	"go.podman.io/common/libnetwork/types"
	"go.podman.io/storage/pkg/idtools"
)

// Info is the overall struct that describes the host system
// running libpod/podman
// swagger:model LibpodInfo
type Info struct {
	Host       *HostInfo      `json:"host"`
	Store      *StoreInfo     `json:"store"`
	Registries map[string]any `json:"registries"`
	Plugins    Plugins        `json:"plugins"`
	Version    Version        `json:"version"`
}

// SecurityInfo describes the libpod host
type SecurityInfo struct {
	AppArmorEnabled     bool   `json:"apparmorEnabled"`
	DefaultCapabilities string `json:"capabilities"`
	Rootless            bool   `json:"rootless"`
	SECCOMPEnabled      bool   `json:"seccompEnabled"`
	SECCOMPProfilePath  string `json:"seccompProfilePath"`
	SELinuxEnabled      bool   `json:"selinuxEnabled"`
}

// HostInfo describes the libpod host
type HostInfo struct {
	Arch               string            `json:"arch"`
	BuildahVersion     string            `json:"buildahVersion"`
	CgroupManager      string            `json:"cgroupManager"`
	CgroupsVersion     string            `json:"cgroupVersion"`
	CgroupControllers  []string          `json:"cgroupControllers"`
	CDISpecDirs        []string          `json:"cdiSpecDirs"`
	DiscoveredDevices  []DeviceInfo      `json:"discoveredDevices,omitempty"`
	Conmon             *ConmonInfo       `json:"conmon"`
	CPUs               int               `json:"cpus"`
	CPUUtilization     *CPUUsage         `json:"cpuUtilization"`
	DatabaseBackend    string            `json:"databaseBackend"`
	Distribution       DistributionInfo  `json:"distribution"`
	EventLogger        string            `json:"eventLogger"`
	FreeLocks          *uint32           `json:"freeLocks,omitempty"`
	Hostname           string            `json:"hostname"`
	IDMappings         IDMappings        `json:"idMappings"`
	Kernel             string            `json:"kernel"`
	LogDriver          string            `json:"logDriver"`
	MemFree            int64             `json:"memFree"`
	MemAvailable       int64             `json:"memAvailable"`
	MemTotal           int64             `json:"memTotal"`
	NetworkBackend     string            `json:"networkBackend"`
	NetworkBackendInfo types.NetworkInfo `json:"networkBackendInfo"`
	OCIRuntime         *OCIRuntimeInfo   `json:"ociRuntime"`
	OS                 string            `json:"os"`
	// RemoteSocket returns the UNIX domain socket the Podman service is listening on
	RemoteSocket *RemoteSocket `json:"remoteSocket,omitempty"`
	// RootlessNetworkCmd returns the default rootless network command (pasta)
	RootlessNetworkCmd string `json:"rootlessNetworkCmd"`
	// RootlessPortForwarder returns the port forwarding mechanism for rootless
	// bridge networks: "rootlessport" (default) or "pasta" (experimental)
	RootlessPortForwarder string         `json:"rootlessPortForwarder"`
	RuntimeInfo           map[string]any `json:"runtimeInfo,omitempty"`
	// ServiceIsRemote is true when the podman/libpod service is remote to the client
	ServiceIsRemote bool         `json:"serviceIsRemote"`
	Security        SecurityInfo `json:"security"`
	Pasta           PastaInfo    `json:"pasta"`

	SwapFree  int64  `json:"swapFree"`
	SwapTotal int64  `json:"swapTotal"`
	Uptime    string `json:"uptime"`
	Variant   string `json:"variant"`
	Linkmode  string `json:"linkmode"`

	EmulatedArchitectures []string `json:"emulatedArchitectures,omitempty"`
}

// DeviceInfo describes a device discovered by a device source.
type DeviceInfo struct {
	Source string `json:"source"`
	ID     string `json:"id"`
}

// RemoteSocket describes information about the API socket
type RemoteSocket struct {
	Path   string `json:"path,omitempty"`
	Exists bool   `json:"exists"`
}

// PastaInfo describes the pasta executable that is being used
type PastaInfo struct {
	Executable string `json:"executable"`
	Package    string `json:"package"`
	Version    string `json:"version"`
}

// IDMappings describe the GID and UID mappings
type IDMappings struct {
	GIDMap []idtools.IDMap `json:"gidmap"`
	UIDMap []idtools.IDMap `json:"uidmap"`
}

// DistributionInfo describes the host distribution for libpod
type DistributionInfo struct {
	Distribution string `json:"distribution"`
	Variant      string `json:"variant,omitempty"`
	Version      string `json:"version"`
	Codename     string `json:"codename,omitempty"`
}

// ConmonInfo describes the conmon executable being used
type ConmonInfo struct {
	Package string `json:"package"`
	Path    string `json:"path"`
	Version string `json:"version"`
}

// OCIRuntimeInfo describes the runtime (crun or runc) being
// used with podman
type OCIRuntimeInfo struct {
	Name    string `json:"name"`
	Package string `json:"package"`
	Path    string `json:"path"`
	Version string `json:"version"`
}

// StoreInfo describes the container storage and its
// attributes
type StoreInfo struct {
	ContainerStore  ContainerStore `json:"containerStore"`
	GraphDriverName string         `json:"graphDriverName"`
	GraphOptions    map[string]any `json:"graphOptions"`
	GraphRoot       string         `json:"graphRoot"`
	// GraphRootAllocated is how much space the graphroot has in bytes
	GraphRootAllocated uint64 `json:"graphRootAllocated"`
	// GraphRootUsed is how much of graphroot is used in bytes
	GraphRootUsed   uint64            `json:"graphRootUsed"`
	GraphStatus     map[string]string `json:"graphStatus"`
	ImageCopyTmpDir string            `json:"imageCopyTmpDir"`
	ImageStore      ImageStore        `json:"imageStore"`
	RunRoot         string            `json:"runRoot"`
	VolumePath      string            `json:"volumePath"`
	TransientStore  bool              `json:"transientStore"`
}

// ImageStore describes the image store.  Right now only the number
// of images present
type ImageStore struct {
	Number int `json:"number"`
}

// ContainerStore describes the quantity of containers in the
// store by status
type ContainerStore struct {
	Number  int `json:"number"`
	Paused  int `json:"paused"`
	Running int `json:"running"`
	Stopped int `json:"stopped"`
}

type Plugins struct {
	Volume  []string `json:"volume"`
	Network []string `json:"network"`
	Log     []string `json:"log"`
	// Authorization is provided for compatibility, will always be nil as Podman has no daemon
	Authorization []string `json:"authorization"`
}

type CPUUsage struct {
	UserPercent   float64 `json:"userPercent"`
	SystemPercent float64 `json:"systemPercent"`
	IdlePercent   float64 `json:"idlePercent"`
}
