// 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"
	"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 := os.CreateTemp("/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 := os.CreateTemp("/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{}))
}
