package versions

import (
	"context"
	"fmt"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

type Container struct {
	id           string
	Names        []string `json:"names"`
	ImageTags    []string `json:"images"`
	ImageDigests []string `json:"digests"`
}

type VersionMonitor struct {
	ctx       context.Context
	dockerClt client.ContainerAPIClient
	imageClt  client.ImageAPIClient
}

func (m *VersionMonitor) buildContainerDetails(c types.Container) (Container, error) {
	var res Container

	details, _, err := m.imageClt.ImageInspectWithRaw(m.ctx, c.Image)
	if err != nil {
		return res, fmt.Errorf("failed to inspect container %s: %w", c.ID, err)
	}
	return Container{
		id:           c.ID,
		Names:        c.Names,
		ImageTags:    details.RepoTags,
		ImageDigests: details.RepoDigests,
	}, nil
}

func (m *VersionMonitor) GetRunningContainers() ([]Container, error) {
	containers, err := m.dockerClt.ContainerList(m.ctx, types.ContainerListOptions{})
	if err != nil {
		return nil, fmt.Errorf("failed to get list of running containers: %w", err)
	}

	res := []Container{}

	for _, c := range containers {
		detailedContainer, err := m.buildContainerDetails(c)
		if err != nil {
			return nil, fmt.Errorf("failed to get details for container %s: %w", c.ID, err)
		}
		res = append(res, detailedContainer)
	}

	return res, nil
}

func New(ctx context.Context) *VersionMonitor {
	clt, err := client.NewClientWithOpts(client.FromEnv)
	if err != nil {
		panic(err)
	}

	return &VersionMonitor{
		ctx:       ctx,
		dockerClt: clt,
		imageClt:  clt,
	}
}
