// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package unix_test

import (
	"bytes"
	"io/ioutil"
	"os"
	"path"
	"testing"

	"golang.org/x/sys/unix"
)

var testData = []byte("This is a test\n")

// stringsFromByteSlice converts a sequence of attributes to a []string.
// On Darwin, each entry is a NULL-terminated string.
func stringsFromByteSlice(buf []byte) []string {
	var result []string
	off := 0
	for i, b := range buf {
		if b == 0 {
			result = append(result, string(buf[off:i]))
			off = i + 1
		}
	}
	return result
}

func createTestFile(t *testing.T, dir string) (f *os.File, cleanup func() error) {
	file, err := ioutil.TempFile(dir, "TestClonefile")
	if err != nil {
		t.Fatal(err)
	}

	_, err = file.Write(testData)
	if err != nil {
		t.Fatal(err)
	}

	err = file.Close()
	if err != nil {
		t.Fatal(err)
	}

	return file, func() error {
		return os.Remove(file.Name())
	}
}

func TestClonefile(t *testing.T) {
	file, cleanup := createTestFile(t, "")
	defer cleanup()

	clonedName := file.Name() + "-cloned"
	err := unix.Clonefile(file.Name(), clonedName, 0)
	if err == unix.ENOSYS || err == unix.ENOTSUP {
		t.Skip("clonefile is not available or supported, skipping test")
	} else if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(clonedName)

	clonedData, err := ioutil.ReadFile(clonedName)
	if err != nil {
		t.Fatal(err)
	}

	if !bytes.Equal(testData, clonedData) {
		t.Errorf("Clonefile: got %q, expected %q", clonedData, testData)
	}
}

func TestClonefileatWithCwd(t *testing.T) {
	file, cleanup := createTestFile(t, "")
	defer cleanup()

	clonedName := file.Name() + "-cloned"
	err := unix.Clonefileat(unix.AT_FDCWD, file.Name(), unix.AT_FDCWD, clonedName, 0)
	if err == unix.ENOSYS || err == unix.ENOTSUP {
		t.Skip("clonefileat is not available or supported, skipping test")
	} else if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(clonedName)

	clonedData, err := ioutil.ReadFile(clonedName)
	if err != nil {
		t.Fatal(err)
	}

	if !bytes.Equal(testData, clonedData) {
		t.Errorf("Clonefileat: got %q, expected %q", clonedData, testData)
	}
}

func TestClonefileatWithRelativePaths(t *testing.T) {
	srcDir, err := ioutil.TempDir("", "src")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(srcDir)

	dstDir, err := ioutil.TempDir("", "dest")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(dstDir)

	srcFd, err := unix.Open(srcDir, unix.O_RDONLY|unix.O_DIRECTORY, 0)
	if err != nil {
		t.Fatal(err)
	}
	defer unix.Close(srcFd)

	dstFd, err := unix.Open(dstDir, unix.O_RDONLY|unix.O_DIRECTORY, 0)
	if err != nil {
		t.Fatal(err)
	}
	defer unix.Close(dstFd)

	srcFile, cleanup := createTestFile(t, srcDir)
	defer cleanup()

	dstFile, err := ioutil.TempFile(dstDir, "TestClonefileat")
	if err != nil {
		t.Fatal(err)
	}
	err = os.Remove(dstFile.Name())
	if err != nil {
		t.Fatal(err)
	}

	src := path.Base(srcFile.Name())
	dst := path.Base(dstFile.Name())
	err = unix.Clonefileat(srcFd, src, dstFd, dst, 0)
	if err == unix.ENOSYS || err == unix.ENOTSUP {
		t.Skip("clonefileat is not available or supported, skipping test")
	} else if err != nil {
		t.Fatal(err)
	}

	clonedData, err := ioutil.ReadFile(dstFile.Name())
	if err != nil {
		t.Fatal(err)
	}

	if !bytes.Equal(testData, clonedData) {
		t.Errorf("Clonefileat: got %q, expected %q", clonedData, testData)
	}
}

func TestFclonefileat(t *testing.T) {
	file, cleanup := createTestFile(t, "")
	defer cleanup()

	fd, err := unix.Open(file.Name(), unix.O_RDONLY, 0)
	if err != nil {
		t.Fatal(err)
	}
	defer unix.Close(fd)

	dstFile, err := ioutil.TempFile("", "TestFclonefileat")
	if err != nil {
		t.Fatal(err)
	}
	os.Remove(dstFile.Name())

	err = unix.Fclonefileat(fd, unix.AT_FDCWD, dstFile.Name(), 0)
	if err == unix.ENOSYS || err == unix.ENOTSUP {
		t.Skip("clonefileat is not available or supported, skipping test")
	} else if err != nil {
		t.Fatal(err)
	}

	clonedData, err := ioutil.ReadFile(dstFile.Name())
	if err != nil {
		t.Fatal(err)
	}

	if !bytes.Equal(testData, clonedData) {
		t.Errorf("Fclonefileat: got %q, expected %q", clonedData, testData)
	}
}
