package diffstore

import (
	"bytes"
	"context"
	"image"
	"net/http"
	"runtime"
	"strings"

	"go.skia.org/infra/go/gcs"
	"go.skia.org/infra/go/metrics2"
	"go.skia.org/infra/go/rtcache"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/golden/go/diff"
	"go.skia.org/infra/golden/go/diffstore/common"
	"go.skia.org/infra/golden/go/diffstore/metricsstore"
	"go.skia.org/infra/golden/go/types"
	"go.skia.org/infra/golden/go/validation"
)

const (
	// imgWebPath is the directory where the images are stored.
	imgWebPath = "images"

	// diffsWebPath is the directory where the diff images are stored.
	diffsWebPath = "diffs"

	// bytesPerEncodedImage is the estimated number of bytes an uncompressed images consumes.
	// Used to conservatively estimate the maximum number of items in the cache.
	// See go/gold-in-memory-images for more on the encoded images.
	bytesPerEncodedImage = 1024 * 1024

	// bytesPerDecodedImage is a conservative estimate of the amount of bytes a typical image
	// will take up decoded. This means 4 bytes per pixel with images usually being no bigger than
	// 1000px by 1000px.
	bytesPerDecodedImage = 4 * 1000 * 1000

	// bytesPerDiffMetric is the estimated number of bytes per diff metric.
	// Used to conservatively estimate the maximum number of items in the cache.
	bytesPerDiffMetric = 100

	// In the steady state, most of the diffs have already been calculated and stored, so spinning
	// up workers to fetch them from the metricsstore is somewhat cheap. We should only rarely have
	// to actually compute the diff metric (which requires a short burst of CPU usage).
	maxDiffWorkers = 5000

	cacheSizeMetrics = "diffstore_cache_size"
)

// MemDiffStore implements the diff.DiffStore interface.
type MemDiffStore struct {
	// diffMetricsCache caches and calculates diff metrics.
	diffMetricsCache rtcache.ReadThroughCache

	// decodedImageCache caches the pixels of decoded images.
	decodedImageCache rtcache.ReadThroughCache

	// imgLoader fetches and caches images.
	imgLoader *ImageLoader

	// metricsStore persists diff metrics.
	metricsStore metricsstore.MetricsStore
}

// NewMemDiffStore returns a new instance of MemDiffStore.
// 'gigs' is the approximate number of gigs to use for caching. This is not the
// exact amount memory that will be used, but a tuning parameter to increase
// or decrease memory used. If 'gigs' is 0 nothing will be cached in memory.
func NewMemDiffStore(client gcs.GCSClient, gsImageBaseDir string, gigs int, mStore metricsstore.MetricsStore) (*MemDiffStore, error) {
	imageCacheCount, diffCacheCount := getCacheCounts(gigs)

	// Set up image retrieval, caching and serving.
	sklog.Debugf("Creating img loader with cache of size %d", imageCacheCount)
	imgLoader, err := NewImgLoader(client, gsImageBaseDir, imageCacheCount)
	if err != nil {
		return nil, skerr.Wrapf(err, "creating img loader with dir %s", gsImageBaseDir)
	}

	ret := &MemDiffStore{
		imgLoader:    imgLoader,
		metricsStore: mStore,
	}

	// TODO(kjlubick) These read-through caches may make this code unnecessarily hard to follow.
	//   Consider just using an LRU directly.
	sklog.Debugf("Creating diffMetricsCache of size %d", diffCacheCount)
	if ret.diffMetricsCache, err = rtcache.New(ret.diffMetricsWorker, diffCacheCount, maxDiffWorkers); err != nil {
		return nil, skerr.Wrapf(err, "creating diffMeticsCache of size %d with max of %d workers", diffCacheCount, maxDiffWorkers)
	}

	// Limit the amount of decoding that can be done at once to the number of CPUs, since that can
	// be pretty CPU intensive.
	if ret.decodedImageCache, err = rtcache.New(ret.decodedImageWorker, imageCacheCount, runtime.NumCPU()); err != nil {
		return nil, skerr.Wrapf(err, "creating decodedImageCache of size %d with max of %d workers", imageCacheCount, runtime.NumCPU())
	}

	return ret, nil
}

// Get implements the DiffStore interface.
func (m *MemDiffStore) Get(ctx context.Context, mainDigest types.Digest, rightDigests types.DigestSlice) (map[types.Digest]*diff.DiffMetrics, error) {
	if mainDigest == "" {
		return nil, skerr.Fmt("Received empty dMain digest.")
	}

	diffIDs := make([]string, 0, len(rightDigests))
	digests := make(types.DigestSlice, 0, len(rightDigests))
	for _, right := range rightDigests {
		// Don't compare the digest to itself, if somehow, mainDigest is in rightDigests.
		if mainDigest == right {
			continue
		}
		diffIDs = append(diffIDs, common.DiffID(mainDigest, right))
		digests = append(digests, right)
	}

	diffMetrics, err := m.diffMetricsCache.GetAll(ctx, diffIDs)
	if err != nil {
		return nil, skerr.Wrapf(err, "getting diffs for %s against %d other digests", mainDigest, len(digests))
	}

	diffMap := make(map[types.Digest]*diff.DiffMetrics, len(digests))
	for i, dm := range diffMetrics {
		// this nil check is likely just being paranoid.
		if dm != nil {
			diffMap[digests[i]] = dm.(*diff.DiffMetrics)
		}
	}

	metrics2.GetInt64Metric(cacheSizeMetrics, map[string]string{
		"type": "metrics",
	}).Update(int64(m.diffMetricsCache.Len()))

	return diffMap, nil
}

// PurgeDigests implements the DiffStore interface.
func (m *MemDiffStore) PurgeDigests(ctx context.Context, digests types.DigestSlice, purgeGCS bool) error {
	// We remove the given digests from the various places where they might
	// be stored. None of the purge steps should return an error if the digests
	// related information is missing. So any error indicates a bigger problem in the
	// underlying system, i.e.issues with disk etc., that needs to be investigated
	// by hand. Since we remove the digests from the failureStore last, we will
	// not loose the vital information of what digests failed in the first place.

	// Remove the images from, the image cache, disk and GCS if necessary.
	if err := m.imgLoader.purgeImages(ctx, digests, purgeGCS); err != nil {
		return skerr.Wrapf(err, "purging %v (fromGCS: %t)", digests, purgeGCS)
	}

	// Remove the diff metrics from the cache if they exist.
	digestSet := make(types.DigestSet, len(digests))
	for _, d := range digests {
		digestSet[d] = true
	}
	removeKeys := make([]string, 0, len(digests))
	for _, key := range m.diffMetricsCache.Keys() {
		d1, d2 := common.SplitDiffID(key)
		if digestSet[d1] || digestSet[d2] {
			removeKeys = append(removeKeys, key)
		}
	}
	m.diffMetricsCache.Remove(removeKeys)

	if err := m.metricsStore.PurgeDiffMetrics(ctx, digests); err != nil {
		return skerr.Wrapf(err, "purging diff metrics for %v", digests)
	}

	return nil
}

// ImageHandler implements the DiffStore interface.
func (m *MemDiffStore) ImageHandler(urlPrefix string) (http.Handler, error) {
	handlerFunc := func(w http.ResponseWriter, r *http.Request) {
		// Go's image package has no color profile support and we convert to 8-bit NRGBA to diff,
		// but our source images may have embedded color profiles and be up to 16-bit. So we must
		// at least take care to serve the original .pngs unaltered.
		//
		// TODO(lovisolo): Diff in NRGBA64?
		// TODO(lovisolo): Make sure each pair of images is in the same color space before diffing?
		//                 (They probably are today but it'd be a good sanity check to make sure.)

		dotExt := "." + common.IMG_EXTENSION
		urlPath := r.URL.Path
		sklog.Debugf("diffstore handling %s", urlPath)
		idx := strings.Index(urlPath, "/")
		if idx == -1 {
			noCacheNotFound(w, r)
			return
		}
		dir := urlPath[:idx]

		// Limit the requests to directories with the images and diff images.
		if dir != diffsWebPath && dir != imgWebPath {
			noCacheNotFound(w, r)
			return
		}

		// Get the file that was requested and verify that it's a valid PNG file.
		file := urlPath[idx+1:]
		if (len(file) <= len(dotExt)) || (!strings.HasSuffix(file, dotExt)) {
			noCacheNotFound(w, r)
			return
		}

		// Trim the image extension to get the image ID.
		imgID := urlPath[idx+1 : len(urlPath)-len(dotExt)]
		imgDigest := types.Digest(imgID)

		// Cache images for 12 hours.
		w.Header().Set("Cache-Control", "public, max-age=43200")

		if dir == imgWebPath {
			// Validate the requested image ID.
			if !validation.IsValidDigest(imgID) {
				noCacheNotFound(w, r)
				return
			}

			// Retrieve the image from the in-memory cache.
			imgs, err := m.imgLoader.Get(r.Context(), types.DigestSlice{imgDigest})
			if err != nil {
				sklog.Errorf("Error retrieving digest: %s", imgID)
				noCacheNotFound(w, r)
				return
			}

			// Write output image to the http.ResponseWriter. Content-Type is set automatically
			// based on the first 512 bytes of written data. See docs for ResponseWriter.Write()
			// for details.
			if _, err := w.Write(imgs[0]); err != nil {
				sklog.Errorf("Error writing image to http.ResponseWriter: %s", err)
				noCacheNotFound(w, r)
			}
		} else {
			// Validate the requested diff image ID.
			if !validation.IsValidDiffImgID(imgID) {
				noCacheNotFound(w, r)
				return
			}

			// Extract the left and right image digests.
			leftDigest, rightDigest := common.SplitDiffID(imgID)

			// Retrieve the images from the in-memory cache.
			imgs, err := m.decodedImageCache.GetAll(r.Context(), []string{string(leftDigest), string(rightDigest)})
			if err != nil {
				sklog.Errorf("Error retrieving and decoding digests to compute diff: %s", imgID)
				noCacheNotFound(w, r)
				return
			}

			// Compute the diff image.
			leftImg, rightImg := imgs[0].(*image.NRGBA), imgs[1].(*image.NRGBA)
			_, diffImg := diff.PixelDiff(leftImg, rightImg)

			// Write output image to the http.ResponseWriter. Content-Type is set automatically
			// based on the first 512 bytes of written data. See docs for ResponseWriter.Write()
			// for details.
			//
			// The encoding step below does not take color profiles into account. This is fine since
			// both the left and right images used to compute the diff are in the same color space,
			// and also because the resulting diff image is just a visual approximation of the
			// differences between the left and right images.
			if err := common.EncodeImg(w, diffImg); err != nil {
				sklog.Errorf("Error encoding diff image: %s", err)
				noCacheNotFound(w, r)
			}
		}
	}

	sklog.Infof("Created diffstore")

	// The above function relies on the URL prefix being stripped.
	return http.StripPrefix(urlPrefix, http.HandlerFunc(handlerFunc)), nil
}

// noCacheNotFound disables caching and returns a 404.
func noCacheNotFound(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
	http.NotFound(w, r)
}

// diffMetricsWorker calculates the diff if it's not in the cache.
func (m *MemDiffStore) diffMetricsWorker(ctx context.Context, ids []string) ([]interface{}, error) {
	// Load the metrics from the store if they are there.
	var missedIndexes []int
	rv := make([]interface{}, len(ids))
	if xdm, err := m.metricsStore.LoadDiffMetrics(ctx, ids); err != nil {
		sklog.Warningf("Could not load diff metrics from cache for %s, going to recompute them all (err: %s)", ids, err)
		for i := range ids {
			missedIndexes = append(missedIndexes, i)
		}
	} else {
		for i, dm := range xdm {
			if dm != nil {
				rv[i] = dm
			} else {
				missedIndexes = append(missedIndexes, i)
			}
		}
		if len(missedIndexes) == 0 {
			return rv, nil
		}
	}

	for _, missed := range missedIndexes {
		t := metrics2.NewTimer("gold_compute_diff_cycle")
		id := ids[missed]
		leftDigest, rightDigest := common.SplitDiffID(id)

		imgs, err := m.decodedImageCache.GetAll(ctx, []string{string(leftDigest), string(rightDigest)})
		if err != nil {
			return nil, skerr.Wrapf(err, "retrieving and decoding the following digests: %s, %s", leftDigest, rightDigest)
		}

		// Compute the diff image.
		leftImg, rightImg := imgs[0].(*image.NRGBA), imgs[1].(*image.NRGBA)
		diffMetrics := diff.ComputeDiffMetrics(leftImg, rightImg)

		if err := m.metricsStore.SaveDiffMetrics(ctx, id, diffMetrics); err != nil {
			sklog.Warningf("Warning - could not store diff metric: %s", err)
		}
		rv[missed] = diffMetrics
		t.Stop()
	}

	return rv, nil
}

// decodedImageWorker gets the images from imgLoader (which has a cache to save downloads) and
// decodes them serially. The number of ids is either 1 or 2 (since we only reason about up to
// to images at a time).
func (m *MemDiffStore) decodedImageWorker(ctx context.Context, ids []string) ([]interface{}, error) {
	imgs, err := m.imgLoader.Get(ctx, asDigests(ids))
	if err != nil {
		return nil, skerr.Wrapf(err, "fetching the images")
	}

	rv := make([]interface{}, 0, len(ids))
	for i, imgBytes := range imgs {
		img, err := common.DecodeImg(bytes.NewReader(imgBytes))
		if err != nil {
			return nil, skerr.Wrapf(err, "decoding image with id %s", ids[i])
		}
		rv = append(rv, img)
	}
	return rv, nil
}

// getCacheCounts returns the number of images and diff metrics to cache
// based on the number of GiB provided. We assume that we want to store N images
// and 100 * N diffmetrics and solve the corresponding equation.
// For a given test, there usually aren't more than about 100 digests,
// as per empirical evidence with Skia.
func getCacheCounts(gigs int) (numImages, numDiffs int) {
	if gigs <= 0 {
		return 0, 0
	}

	bytesGig := int64(gigs) * 1024 * 1024 * 1024
	N := bytesGig / (100*bytesPerDiffMetric + bytesPerEncodedImage + bytesPerDecodedImage)

	return int(N), 100 * int(N)
}
