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

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

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

func defaultFSStoreBackend(t *testing.T) (StoreBackend, func()) {
	tmpdir, err := ioutil.TempDir("", "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 = ioutil.WriteFile(filepath.Join(store.(*fs).root, contentDirName, string(dgst.Algorithm()), dgst.Hex()), []byte("foobar2"), 0600)
	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.Hex()), 0700)
	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 := ioutil.TempDir("", "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 = ioutil.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"))
}
