package docker

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/moby/moby/api/types/container"
	"github.com/moby/moby/client"
)

// ContainerStats holds computed CPU and memory usage for a container.
type ContainerStats struct {
	CPUPercent    float64 `json:"cpu_percent"`
	MemoryUsage  int64   `json:"memory_usage"`
	MemoryLimit  int64   `json:"memory_limit"`
	MemoryPercent float64 `json:"memory_percent"`
}

// GetContainerStats retrieves a one-shot stats snapshot for the given container
// and computes CPU and memory percentages.
func (c *Client) GetContainerStats(ctx context.Context, containerID string) (ContainerStats, error) {
	result, err := c.api.ContainerStats(ctx, containerID, client.ContainerStatsOptions{
		Stream:                false,
		IncludePreviousSample: true,
	})
	if err != nil {
		return ContainerStats{}, fmt.Errorf("get container stats %s: %w", containerID, err)
	}
	defer result.Body.Close()

	var stats container.StatsResponse
	if err := json.NewDecoder(result.Body).Decode(&stats); err != nil {
		return ContainerStats{}, fmt.Errorf("decode container stats %s: %w", containerID, err)
	}

	cpuPercent := calculateCPUPercent(stats)
	memUsage := int64(stats.MemoryStats.Usage)
	memLimit := int64(stats.MemoryStats.Limit)
	var memPercent float64
	if memLimit > 0 {
		memPercent = float64(memUsage) / float64(memLimit) * 100.0
	}

	return ContainerStats{
		CPUPercent:    cpuPercent,
		MemoryUsage:  memUsage,
		MemoryLimit:  memLimit,
		MemoryPercent: memPercent,
	}, nil
}

// calculateCPUPercent computes CPU usage percentage from a stats response
// using the delta between current and previous CPU readings.
func calculateCPUPercent(stats container.StatsResponse) float64 {
	cpuDelta := float64(stats.CPUStats.CPUUsage.TotalUsage) - float64(stats.PreCPUStats.CPUUsage.TotalUsage)
	systemDelta := float64(stats.CPUStats.SystemUsage) - float64(stats.PreCPUStats.SystemUsage)

	if systemDelta <= 0 || cpuDelta < 0 {
		return 0.0
	}

	onlineCPUs := float64(stats.CPUStats.OnlineCPUs)
	if onlineCPUs == 0 {
		onlineCPUs = 1
	}

	return (cpuDelta / systemDelta) * onlineCPUs * 100.0
}
