package cache // import "github.com/docker/docker/image/cache"

import (
	"context"
	"fmt"
	"reflect"
	"strings"

	"github.com/containerd/log"
	containertypes "github.com/docker/docker/api/types/container"
	"github.com/docker/docker/builder"
	"github.com/docker/docker/dockerversion"
	"github.com/docker/docker/image"
	"github.com/docker/docker/layer"
	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
	"github.com/pkg/errors"
)

type ImageCacheStore interface {
	Get(image.ID) (*image.Image, error)
	GetByRef(ctx context.Context, refOrId string) (*image.Image, error)
	SetParent(target, parent image.ID) error
	GetParent(target image.ID) (image.ID, error)
	Create(parent *image.Image, image image.Image, extraLayer layer.DiffID) (image.ID, error)
	IsBuiltLocally(id image.ID) (bool, error)
	Children(id image.ID) []image.ID
}

func New(ctx context.Context, store ImageCacheStore, cacheFrom []string) (builder.ImageCache, error) {
	local := &LocalImageCache{store: store}
	if len(cacheFrom) == 0 {
		return local, nil
	}

	cache := &ImageCache{
		store:           store,
		localImageCache: local,
	}

	for _, ref := range cacheFrom {
		img, err := store.GetByRef(ctx, ref)
		if err != nil {
			if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
				return nil, err
			}
			log.G(ctx).Warnf("Could not look up %s for cache resolution, skipping: %+v", ref, err)
			continue
		}
		cache.Populate(img)
	}

	return cache, nil
}

// LocalImageCache is cache based on parent chain.
type LocalImageCache struct {
	store ImageCacheStore
}

// GetCache returns the image id found in the cache
func (lic *LocalImageCache) GetCache(imgID string, config *containertypes.Config, platform ocispec.Platform) (string, error) {
	return getImageIDAndError(getLocalCachedImage(lic.store, image.ID(imgID), config, platform))
}

// ImageCache is cache based on history objects. Requires initial set of images.
type ImageCache struct {
	sources         []*image.Image
	store           ImageCacheStore
	localImageCache *LocalImageCache
}

// Populate adds an image to the cache (to be queried later)
func (ic *ImageCache) Populate(image *image.Image) {
	ic.sources = append(ic.sources, image)
}

// GetCache returns the image id found in the cache
func (ic *ImageCache) GetCache(parentID string, cfg *containertypes.Config, platform ocispec.Platform) (string, error) {
	imgID, err := ic.localImageCache.GetCache(parentID, cfg, platform)
	if err != nil {
		return "", err
	}
	if imgID != "" {
		for _, s := range ic.sources {
			if ic.isParent(s.ID(), image.ID(imgID)) {
				return imgID, nil
			}
		}
	}

	var parent *image.Image
	lenHistory := 0
	if parentID != "" {
		parent, err = ic.store.Get(image.ID(parentID))
		if err != nil {
			return "", errors.Wrapf(err, "unable to find image %v", parentID)
		}
		lenHistory = len(parent.History)
	}

	for _, target := range ic.sources {
		if !isValidParent(target, parent) || !isValidConfig(cfg, target.History[lenHistory]) {
			continue
		}

		if len(target.History)-1 == lenHistory { // last
			if parent != nil {
				if err := ic.store.SetParent(target.ID(), parent.ID()); err != nil {
					return "", errors.Wrapf(err, "failed to set parent for %v to %v", target.ID(), parent.ID())
				}
			}
			return target.ID().String(), nil
		}

		imgID, err := ic.restoreCachedImage(parent, target, cfg)
		if err != nil {
			return "", errors.Wrapf(err, "failed to restore cached image from %q to %v", parentID, target.ID())
		}

		ic.sources = []*image.Image{target} // avoid jumping to different target, tuned for safety atm
		return imgID.String(), nil
	}

	return "", nil
}

func (ic *ImageCache) restoreCachedImage(parent, target *image.Image, cfg *containertypes.Config) (image.ID, error) {
	var history []image.History
	rootFS := image.NewRootFS()
	lenHistory := 0
	if parent != nil {
		history = parent.History
		rootFS = parent.RootFS
		lenHistory = len(parent.History)
	}
	history = append(history, target.History[lenHistory])
	layer := getLayerForHistoryIndex(target, lenHistory)
	if layer != "" {
		rootFS.Append(layer)
	}

	restoredImg := image.Image{
		V1Image: image.V1Image{
			DockerVersion: dockerversion.Version,
			Config:        cfg,
			Architecture:  target.Architecture,
			OS:            target.OS,
			Author:        target.Author,
			Created:       history[len(history)-1].Created,
		},
		RootFS:     rootFS,
		History:    history,
		OSFeatures: target.OSFeatures,
		OSVersion:  target.OSVersion,
	}

	imgID, err := ic.store.Create(parent, restoredImg, layer)
	if err != nil {
		return "", errors.Wrap(err, "failed to create cache image")
	}

	return imgID, nil
}

func (ic *ImageCache) isParent(imgID, parentID image.ID) bool {
	nextParent, err := ic.store.GetParent(imgID)
	if err != nil {
		return false
	}
	if nextParent == parentID {
		return true
	}
	return ic.isParent(nextParent, parentID)
}

func getLayerForHistoryIndex(image *image.Image, index int) layer.DiffID {
	layerIndex := 0
	for i, h := range image.History {
		if i == index {
			if h.EmptyLayer {
				return ""
			}
			break
		}
		if !h.EmptyLayer {
			layerIndex++
		}
	}
	return image.RootFS.DiffIDs[layerIndex] // validate?
}

func isValidConfig(cfg *containertypes.Config, h image.History) bool {
	// todo: make this format better than join that loses data
	return strings.Join(cfg.Cmd, " ") == h.CreatedBy
}

func isValidParent(img, parent *image.Image) bool {
	if len(img.History) == 0 {
		return false
	}
	if parent == nil || len(parent.History) == 0 && len(parent.RootFS.DiffIDs) == 0 {
		return true
	}
	if len(parent.History) >= len(img.History) {
		return false
	}
	if len(parent.RootFS.DiffIDs) > len(img.RootFS.DiffIDs) {
		return false
	}

	for i, h := range parent.History {
		if !reflect.DeepEqual(h, img.History[i]) {
			return false
		}
	}
	for i, d := range parent.RootFS.DiffIDs {
		if d != img.RootFS.DiffIDs[i] {
			return false
		}
	}
	return true
}

func getImageIDAndError(img *image.Image, err error) (string, error) {
	if img == nil || err != nil {
		return "", err
	}
	return img.ID().String(), nil
}

// getLocalCachedImage returns the most recent created image that is a child
// of the image with imgID, that had the same config when it was
// created. nil is returned if a child cannot be found. An error is
// returned if the parent image cannot be found.
func getLocalCachedImage(imageStore ImageCacheStore, parentID image.ID, config *containertypes.Config, platform ocispec.Platform) (*image.Image, error) {
	if config == nil {
		return nil, nil
	}

	var match *image.Image
	for _, id := range imageStore.Children(parentID) {
		img, err := imageStore.Get(id)
		if err != nil {
			return nil, fmt.Errorf("unable to find image %q", id)
		}

		builtLocally, err := imageStore.IsBuiltLocally(id)
		if err != nil {
			log.G(context.TODO()).WithFields(log.Fields{
				"error": err,
				"id":    id,
			}).Warn("failed to check if image was built locally")
			continue
		}
		if !builtLocally {
			continue
		}

		imgPlatform := img.Platform()
		// Discard old linux/amd64 images with empty platform.
		if imgPlatform.OS == "" && imgPlatform.Architecture == "" {
			continue
		}
		if !comparePlatform(platform, imgPlatform) {
			continue
		}

		if compare(&img.ContainerConfig, config) {
			// check for the most up to date match
			if img.Created != nil && (match == nil || match.Created.Before(*img.Created)) {
				match = img
			}
		}
	}
	return match, nil
}
