// +build linux

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

import (
	"io/ioutil"
	"os"
	"os/exec"
	"testing"

	"golang.org/x/sys/unix"
	"gotest.tools/v3/assert"
	"gotest.tools/v3/fs"
)

const imageSize = 64 * 1024 * 1024

// CanTestQuota - checks if xfs prjquota can be tested
// returns a reason if not
func CanTestQuota() (string, bool) {
	if os.Getuid() != 0 {
		return "requires mounts", false
	}
	_, err := exec.LookPath("mkfs.xfs")
	if err != nil {
		return "mkfs.xfs not found in PATH", false
	}
	return "", true
}

// PrepareQuotaTestImage - prepares an xfs prjquota test image
// returns the path the the image on success
func PrepareQuotaTestImage(t *testing.T) (string, error) {
	mkfs, err := exec.LookPath("mkfs.xfs")
	if err != nil {
		return "", err
	}

	// create a sparse image
	imageFile, err := ioutil.TempFile("", "xfs-image")
	if err != nil {
		return "", err
	}
	imageFileName := imageFile.Name()
	if _, err = imageFile.Seek(imageSize-1, 0); err != nil {
		os.Remove(imageFileName)
		return "", err
	}
	if _, err = imageFile.Write([]byte{0}); err != nil {
		os.Remove(imageFileName)
		return "", err
	}
	if err = imageFile.Close(); err != nil {
		os.Remove(imageFileName)
		return "", err
	}

	// The reason for disabling these options is sometimes people run with a newer userspace
	// than kernelspace
	out, err := exec.Command(mkfs, "-m", "crc=0,finobt=0", imageFileName).CombinedOutput()
	if len(out) > 0 {
		t.Log(string(out))
	}
	if err != nil {
		os.Remove(imageFileName)
		return "", err
	}

	return imageFileName, nil
}

// WrapMountTest - wraps a test function such that it has easy access to a mountPoint and testDir
// with guaranteed prjquota or guaranteed no prjquota support.
func WrapMountTest(imageFileName string, enableQuota bool, testFunc func(t *testing.T, mountPoint, backingFsDev, testDir string)) func(*testing.T) {
	return func(t *testing.T) {
		mountOptions := "loop"

		if enableQuota {
			mountOptions = mountOptions + ",prjquota"
		}

		mountPointDir := fs.NewDir(t, "xfs-mountPoint")
		defer mountPointDir.Remove()
		mountPoint := mountPointDir.Path()

		out, err := exec.Command("mount", "-o", mountOptions, imageFileName, mountPoint).CombinedOutput()
		if err != nil {
			_, err := os.Stat("/proc/fs/xfs")
			if os.IsNotExist(err) {
				t.Skip("no /proc/fs/xfs")
			}
		}

		assert.NilError(t, err, "mount failed: %s", out)

		defer func() {
			assert.NilError(t, unix.Unmount(mountPoint, 0))
		}()

		backingFsDev, err := makeBackingFsDev(mountPoint)
		assert.NilError(t, err)

		testDir, err := ioutil.TempDir(mountPoint, "per-test")
		assert.NilError(t, err)
		defer os.RemoveAll(testDir)

		testFunc(t, mountPoint, backingFsDev, testDir)
	}
}

// WrapQuotaTest - wraps a test function such that is has easy and guaranteed access to a quota Control
// instance with a quota test dir under its control.
func WrapQuotaTest(testFunc func(t *testing.T, ctrl *Control, mountPoint, testDir, testSubDir string)) func(t *testing.T, mountPoint, backingFsDev, testDir string) {
	return func(t *testing.T, mountPoint, backingFsDev, testDir string) {
		ctrl, err := NewControl(testDir)
		assert.NilError(t, err)

		testSubDir, err := ioutil.TempDir(testDir, "quota-test")
		assert.NilError(t, err)
		testFunc(t, ctrl, mountPoint, testDir, testSubDir)
	}
}
