// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package loop

import (
	"encoding/binary"
	"io"
	"io/ioutil"
	"math"
	"os"
	"runtime"
	"syscall"
	"testing"
	"unsafe"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"golang.org/x/sys/unix"
)

// Write a test file with a very specific pattern (increasing little-endian 16
// bit unsigned integers) to detect offset correctness. File is always 128KiB
// large (2^16 * 2 bytes).
func makeTestFile() *os.File {
	f, err := ioutil.TempFile("/tmp", "")
	if err != nil {
		panic(err)
	}
	for i := 0; i <= math.MaxUint16; i++ {
		if err := binary.Write(f, binary.LittleEndian, uint16(i)); err != nil {
			panic(err)
		}
	}
	if _, err := f.Seek(0, io.SeekStart); err != nil {
		panic(err)
	}
	return f
}

func getBlkdevSize(f *os.File) (size uint64) {
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), unix.BLKGETSIZE64, uintptr(unsafe.Pointer(&size))); err != 0 {
		panic(err)
	}
	return
}

func getOffsetFromContent(dev *Device) (firstIndex uint16) {
	if err := binary.Read(dev.dev, binary.LittleEndian, &firstIndex); err != nil {
		panic(err)
	}
	firstIndex *= 2 // 2 bytes per index
	return
}

func setupCreate(t *testing.T, config Config) *Device {
	f := makeTestFile()
	dev, err := Create(f, config)
	defer f.Close()
	assert.NoError(t, err)
	t.Cleanup(func() {
		if dev != nil {
			dev.Remove()
		}
		os.Remove(f.Name())
	})
	if dev == nil {
		t.FailNow()
	}
	return dev
}

func TestDeviceAccessors(t *testing.T) {
	if os.Getenv("IN_KTEST") != "true" {
		t.Skip("Not in ktest")
	}
	dev := setupCreate(t, Config{})

	devPath, err := dev.DevPath()
	assert.NoError(t, err)
	require.Equal(t, "/dev/loop0", devPath)

	var stat unix.Stat_t
	assert.NoError(t, unix.Stat("/dev/loop0", &stat))
	devNum, err := dev.Dev()
	assert.NoError(t, err)
	require.Equal(t, stat.Rdev, devNum)

	backingFile, err := dev.BackingFilePath()
	assert.NoError(t, err)
	// The filename of the temporary file is not available in this context, but
	// we know that the file needs to be in /tmp, which should be a good-enough
	// test.
	assert.Contains(t, backingFile, "/tmp/")
}

func TestCreate(t *testing.T) {
	if os.Getenv("IN_KTEST") != "true" {
		t.Skip("Not in ktest")
	}
	t.Parallel()
	tests := []struct {
		name     string
		config   Config
		validate func(t *testing.T, dev *Device)
	}{
		{"NoOpts", Config{}, func(t *testing.T, dev *Device) {
			require.Equal(t, uint64(128*1024), getBlkdevSize(dev.dev))
			require.Equal(t, uint16(0), getOffsetFromContent(dev))

			_, err := dev.dev.WriteString("test")
			assert.NoError(t, err)
		}},
		{"DirectIO", Config{Flags: FlagDirectIO}, func(t *testing.T, dev *Device) {
			require.Equal(t, uint64(128*1024), getBlkdevSize(dev.dev))

			_, err := dev.dev.WriteString("test")
			assert.NoError(t, err)
		}},
		{"ReadOnly", Config{Flags: FlagReadOnly}, func(t *testing.T, dev *Device) {
			_, err := dev.dev.WriteString("test")
			assert.Error(t, err)
		}},
		{"Mapping", Config{BlockSize: 512, SizeLimit: 2048, Offset: 4096}, func(t *testing.T, dev *Device) {
			assert.Equal(t, uint16(4096), getOffsetFromContent(dev))
			assert.Equal(t, uint64(2048), getBlkdevSize(dev.dev))
		}},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			dev := setupCreate(t, test.config)
			test.validate(t, dev)
			assert.NoError(t, dev.Remove())
		})
	}
}

func TestOpenBadDevice(t *testing.T) {
	if os.Getenv("IN_KTEST") != "true" {
		t.Skip("Not in ktest")
	}
	dev, err := Open("/dev/null")
	require.Error(t, err)
	if dev != nil { // Prevent leaks in case this test fails
		dev.Close()
	}
}

func TestOpen(t *testing.T) {
	if os.Getenv("IN_KTEST") != "true" {
		t.Skip("Not in ktest")
	}
	f := makeTestFile()
	defer os.Remove(f.Name())
	defer f.Close()
	dev, err := Create(f, Config{})
	assert.NoError(t, err)
	path, err := dev.DevPath()
	assert.NoError(t, err)
	assert.NoError(t, dev.Close())
	reopenedDev, err := Open(path)
	assert.NoError(t, err)
	defer reopenedDev.Remove()
	reopenedDevPath, err := reopenedDev.DevPath()
	assert.NoError(t, err)
	require.Equal(t, path, reopenedDevPath) // Still needs to be the same device
}

func TestResize(t *testing.T) {
	if os.Getenv("IN_KTEST") != "true" {
		t.Skip("Not in ktest")
	}
	f, err := ioutil.TempFile("/tmp", "")
	assert.NoError(t, err)
	empty1K := make([]byte, 1024)
	for i := 0; i < 64; i++ {
		_, err := f.Write(empty1K)
		assert.NoError(t, err)
	}
	dev, err := Create(f, Config{})
	assert.NoError(t, err)
	require.Equal(t, uint64(64*1024), getBlkdevSize(dev.dev))
	for i := 0; i < 32; i++ {
		_, err := f.Write(empty1K)
		assert.NoError(t, err)
	}
	assert.NoError(t, f.Sync())
	assert.NoError(t, dev.RefreshSize())
	require.Equal(t, uint64(96*1024), getBlkdevSize(dev.dev))
}

func TestStructSize(t *testing.T) {
	if runtime.GOOS != "linux" && runtime.GOARCH != "amd64" {
		t.Skip("Reference value not available")
	}
	require.Equal(t, uintptr(304), unsafe.Sizeof(loopConfig{}))
}
