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

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"os"
	"path/filepath"
	"testing"

	"github.com/opencontainers/go-digest"
	"gotest.tools/v3/assert"
	is "gotest.tools/v3/assert/cmp"
)

func defaultFSStoreBackend(t *testing.T) (StoreBackend, func()) {
	tmpdir, err := os.MkdirTemp("", "images-fs-store")
	assert.Check(t, err)

	fsBackend, err := NewFSStoreBackend(tmpdir)
	assert.Check(t, err)

	return fsBackend, func() { os.RemoveAll(tmpdir) }
}

func TestFSGetInvalidData(t *testing.T) {
	store, cleanup := defaultFSStoreBackend(t)
	defer cleanup()

	dgst, err := store.Set([]byte("foobar"))
	assert.Check(t, err)

	err = os.WriteFile(filepath.Join(store.(*fs).root, contentDirName, string(dgst.Algorithm()), dgst.Encoded()), []byte("foobar2"), 0o600)
	assert.Check(t, err)

	_, err = store.Get(dgst)
	assert.Check(t, is.ErrorContains(err, "failed to verify"))
}

func TestFSInvalidSet(t *testing.T) {
	store, cleanup := defaultFSStoreBackend(t)
	defer cleanup()

	id := digest.FromBytes([]byte("foobar"))
	err := os.Mkdir(filepath.Join(store.(*fs).root, contentDirName, string(id.Algorithm()), id.Encoded()), 0o700)
	assert.Check(t, err)

	_, err = store.Set([]byte("foobar"))
	assert.Check(t, is.ErrorContains(err, "failed to write digest data"))
}

func TestFSInvalidRoot(t *testing.T) {
	tmpdir, err := os.MkdirTemp("", "images-fs-store")
	assert.Check(t, err)
	defer os.RemoveAll(tmpdir)

	tcases := []struct {
		root, invalidFile string
	}{
		{"root", "root"},
		{"root", "root/content"},
		{"root", "root/metadata"},
	}

	for _, tc := range tcases {
		root := filepath.Join(tmpdir, tc.root)
		filePath := filepath.Join(tmpdir, tc.invalidFile)
		err := os.MkdirAll(filepath.Dir(filePath), 0700)
		assert.Check(t, err)

		f, err := os.Create(filePath)
		assert.Check(t, err)
		f.Close()

		_, err = NewFSStoreBackend(root)
		assert.Check(t, is.ErrorContains(err, "failed to create storage backend"))

		os.RemoveAll(root)
	}
}

func TestFSMetadataGetSet(t *testing.T) {
	store, cleanup := defaultFSStoreBackend(t)
	defer cleanup()

	id, err := store.Set([]byte("foo"))
	assert.Check(t, err)

	id2, err := store.Set([]byte("bar"))
	assert.Check(t, err)

	tcases := []struct {
		id    digest.Digest
		key   string
		value []byte
	}{
		{id, "tkey", []byte("tval1")},
		{id, "tkey2", []byte("tval2")},
		{id2, "tkey", []byte("tval3")},
	}

	for _, tc := range tcases {
		err = store.SetMetadata(tc.id, tc.key, tc.value)
		assert.Check(t, err)

		actual, err := store.GetMetadata(tc.id, tc.key)
		assert.Check(t, err)

		assert.Check(t, is.DeepEqual(tc.value, actual))
	}

	_, err = store.GetMetadata(id2, "tkey2")
	assert.Check(t, is.ErrorContains(err, "failed to read metadata"))

	id3 := digest.FromBytes([]byte("baz"))
	err = store.SetMetadata(id3, "tkey", []byte("tval"))
	assert.Check(t, is.ErrorContains(err, "failed to get digest"))

	_, err = store.GetMetadata(id3, "tkey")
	assert.Check(t, is.ErrorContains(err, "failed to get digest"))
}

func TestFSInvalidWalker(t *testing.T) {
	store, cleanup := defaultFSStoreBackend(t)
	defer cleanup()

	fooID, err := store.Set([]byte("foo"))
	assert.Check(t, err)

	err = os.WriteFile(filepath.Join(store.(*fs).root, contentDirName, "sha256/foobar"), []byte("foobar"), 0600)
	assert.Check(t, err)

	n := 0
	err = store.Walk(func(id digest.Digest) error {
		assert.Check(t, is.Equal(fooID, id))
		n++
		return nil
	})
	assert.Check(t, err)
	assert.Check(t, is.Equal(1, n))
}

func TestFSGetSet(t *testing.T) {
	store, cleanup := defaultFSStoreBackend(t)
	defer cleanup()

	type tcase struct {
		input    []byte
		expected digest.Digest
	}
	tcases := []tcase{
		{[]byte("foobar"), digest.Digest("sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2")},
	}

	randomInput := make([]byte, 8*1024)
	_, err := rand.Read(randomInput)
	assert.Check(t, err)

	// skipping use of digest pkg because it is used by the implementation
	h := sha256.New()
	_, err = h.Write(randomInput)
	assert.Check(t, err)

	tcases = append(tcases, tcase{
		input:    randomInput,
		expected: digest.Digest("sha256:" + hex.EncodeToString(h.Sum(nil))),
	})

	for _, tc := range tcases {
		id, err := store.Set(tc.input)
		assert.Check(t, err)
		assert.Check(t, is.Equal(tc.expected, id))
	}

	for _, tc := range tcases {
		data, err := store.Get(tc.expected)
		assert.Check(t, err)
		assert.Check(t, is.DeepEqual(tc.input, data))
	}
}

func TestFSGetUnsetKey(t *testing.T) {
	store, cleanup := defaultFSStoreBackend(t)
	defer cleanup()

	for _, key := range []digest.Digest{"foobar:abc", "sha256:abc", "sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2a"} {
		_, err := store.Get(key)
		assert.Check(t, is.ErrorContains(err, "failed to get digest"))
	}
}

func TestFSGetEmptyData(t *testing.T) {
	store, cleanup := defaultFSStoreBackend(t)
	defer cleanup()

	for _, emptyData := range [][]byte{nil, {}} {
		_, err := store.Set(emptyData)
		assert.Check(t, is.ErrorContains(err, "invalid empty data"))
	}
}

func TestFSDelete(t *testing.T) {
	store, cleanup := defaultFSStoreBackend(t)
	defer cleanup()

	id, err := store.Set([]byte("foo"))
	assert.Check(t, err)

	id2, err := store.Set([]byte("bar"))
	assert.Check(t, err)

	err = store.Delete(id)
	assert.Check(t, err)

	_, err = store.Get(id)
	assert.Check(t, is.ErrorContains(err, "failed to get digest"))

	_, err = store.Get(id2)
	assert.Check(t, err)

	err = store.Delete(id2)
	assert.Check(t, err)

	_, err = store.Get(id2)
	assert.Check(t, is.ErrorContains(err, "failed to get digest"))
}

func TestFSWalker(t *testing.T) {
	store, cleanup := defaultFSStoreBackend(t)
	defer cleanup()

	id, err := store.Set([]byte("foo"))
	assert.Check(t, err)

	id2, err := store.Set([]byte("bar"))
	assert.Check(t, err)

	tcases := make(map[digest.Digest]struct{})
	tcases[id] = struct{}{}
	tcases[id2] = struct{}{}
	n := 0
	err = store.Walk(func(id digest.Digest) error {
		delete(tcases, id)
		n++
		return nil
	})
	assert.Check(t, err)
	assert.Check(t, is.Equal(2, n))
	assert.Check(t, is.Len(tcases, 0))
}

func TestFSWalkerStopOnError(t *testing.T) {
	store, cleanup := defaultFSStoreBackend(t)
	defer cleanup()

	id, err := store.Set([]byte("foo"))
	assert.Check(t, err)

	tcases := make(map[digest.Digest]struct{})
	tcases[id] = struct{}{}
	err = store.Walk(func(id digest.Digest) error {
		return errors.New("what")
	})
	assert.Check(t, is.ErrorContains(err, "what"))
}
