package dkms

import (
	"context"
	"os"
	"path"
	"sort"
	"strings"
	"testing"

	"cos.googlesource.com/cos/tools.git/src/pkg/fakes"
	"cos.googlesource.com/cos/tools.git/src/pkg/fs"
	"cos.googlesource.com/cos/tools.git/src/pkg/gcs"
	"cos.googlesource.com/cos/tools.git/src/pkg/kernel"
	"github.com/google/go-cmp/cmp"
)

func TestBuild(t *testing.T) {
	options := &Options{
		Force:                    false,
		MakeVariables:            "",
		InstallBuildDependencies: false,
	}

	trees := &Trees{
		Dkms:   t.TempDir(),
		Source: "testdata/source-tree",
		Kernel: "testdata/kernel-source/lib/modules/6.1.100/build",
	}

	pkg := &Package{
		Name:          "mymodule",
		Version:       "1.0",
		KernelVersion: "6.1.100",
		Arch:          "x86_64",
		BuildId:       "18244.151.14",
		Trees:         trees,
	}

	err := Build(pkg, options)
	if err != nil {
		t.Fatalf("%v", err)
	}

	makefilePath := path.Join(trees.Dkms, "mymodule", "1.0", "6.1.100", "x86_64", "18244.151.14", "source", "Makefile")
	if !fs.IsFile(makefilePath) {
		t.Fatalf("expected to find file %s after adding sources", makefilePath)
	}

	buildMakefilePath := path.Join(trees.Dkms, "mymodule", "1.0", "6.1.100", "x86_64", "18244.151.14", "build", "Makefile")
	if !fs.IsFile(buildMakefilePath) {
		t.Fatalf("expected to find file %s after building", buildMakefilePath)
	}

	builtModulePath := path.Join(trees.Dkms, "mymodule", "1.0", "6.1.100", "x86_64", "18244.151.14", "build", "mymodule.ko")
	if !fs.IsFile(builtModulePath) {
		t.Fatalf("expected to find file %s after building", builtModulePath)
	}
}

func TestBuildModuleSigning(t *testing.T) {
	signingDir := t.TempDir()

	options := &Options{
		Force:                    false,
		MakeVariables:            "",
		InstallBuildDependencies: false,
		Hash:                     "sha256",
		PrivateKeyPath:           path.Join(signingDir, "rsaKey.pem"),
		CertificatePath:          path.Join(signingDir, "cert.der"),
	}

	trees := &Trees{
		Dkms:   t.TempDir(),
		Source: "testdata/source-tree",
		Kernel: "testdata/kernel-source/lib/modules/6.1.100/build",
	}

	pkg := &Package{
		Name:          "mymodule",
		Version:       "1.0",
		KernelVersion: "6.1.100",
		Arch:          "x86_64",
		BuildId:       "18244.151.14",
		Trees:         trees,
	}

	key, keyBytes, err := generateRSAPrivateKey()
	if err != nil {
		t.Fatalf("failed to generate rsa key: %v", err)
	}
	if err = os.WriteFile(options.PrivateKeyPath, keyBytes, 0600); err != nil {
		t.Fatalf("failed to write rsa key to file (%s): %v", options.PrivateKeyPath, err)
	}

	certBytes, err := generateCertificate(key)
	if err != nil {
		t.Fatalf("failed to generate certificate: %v", err)
	}
	if err = os.WriteFile(options.CertificatePath, certBytes, 0600); err != nil {
		t.Fatalf("failed to write certificate to file (%s): %v", options.CertificatePath, err)
	}

	err = Build(pkg, options)
	if err != nil {
		t.Fatalf("%v", err)
	}

	builtModulePath := path.Join(trees.Dkms, "mymodule", "1.0", "6.1.100", "x86_64", "18244.151.14", "build", "mymodule.ko")
	if !fs.IsFile(builtModulePath) {
		t.Fatalf("expected to find file %s after building", builtModulePath)
	}

	moduleBytes, err := os.ReadFile(builtModulePath)
	if err != nil {
		t.Fatalf("failed to read module: %s", builtModulePath)
	}
	expectedMessage := []byte("~Module signature appended~\n")

	diff := cmp.Diff(expectedMessage, moduleBytes[len(moduleBytes)-len(expectedMessage):])
	if diff != "" {
		t.Fatalf("expected signature did not match\ndiff: %s", diff)
	}
}

func TestCachedBuild(t *testing.T) {
	options := &Options{
		Force:                    false,
		MakeVariables:            "",
		InstallBuildDependencies: false,
		Upload:                   true,
	}

	trees := &Trees{
		Dkms:   t.TempDir(),
		Source: "testdata/source-tree",
		Kernel: "testdata/kernel-source/lib/modules/6.1.100/build",
	}

	pkg := &Package{
		Name:          "mymodule",
		Version:       "1.0",
		KernelVersion: "6.1.100",
		Arch:          "x86_64",
		BuildId:       "18244.151.14",
		Trees:         trees,
	}

	ctx := context.Background()
	fakeGCS := fakes.GCSForTest(t)
	fakeGCS.LogMissing = false
	bucket := gcs.NewGCSBucket(fakeGCS.Client, "test", "dkms")
	err := CachedBuild(ctx, pkg, bucket, options)
	if err != nil {
		t.Fatalf("%v", err)
	}

	cacheMakefilePath := path.Join("mymodule", "1.0", "6.1.100", "x86_64", "18244.151.14", "source", "Makefile")
	makefilePath := path.Join(trees.Dkms, cacheMakefilePath)
	if !fs.IsFile(makefilePath) {
		t.Fatalf("expected to find file %s after adding sources", makefilePath)
	}

	buildMakefilePath := path.Join(trees.Dkms, "mymodule", "1.0", "6.1.100", "x86_64", "18244.151.14", "build", "Makefile")
	if !fs.IsFile(buildMakefilePath) {
		t.Fatalf("expected to find file %s after building", makefilePath)
	}

	cacheBuiltModulePath := path.Join("mymodule", "1.0", "6.1.100", "x86_64", "18244.151.14", "build", "mymodule.ko")
	builtModulePath := path.Join(trees.Dkms, cacheBuiltModulePath)
	if !fs.IsFile(builtModulePath) {
		t.Fatalf("expected to find file %s after building", makefilePath)
	}

	cachedMakefileExists, err := bucket.Exists(ctx, cacheMakefilePath)
	if err != nil {
		t.Fatalf("failed to check if %s exists", cacheMakefilePath)
	}
	if !cachedMakefileExists {
		t.Fatalf("expected to find file %s in cache after adding sources", cacheMakefilePath)
	}

	cachedModuleExists, err := bucket.Exists(ctx, cacheBuiltModulePath)
	if err != nil {
		t.Fatalf("failed to check if %s exists", cacheBuiltModulePath)
	}
	if !cachedModuleExists {
		t.Fatalf("expected to find file %s in cache after building modules", cacheBuiltModulePath)
	}
}

func TestDefaultMakeVariables(t *testing.T) {
	trees := &Trees{
		Kernel: "testdata/kernel-sources",
	}
	pkg := &Package{
		Arch:  "abc",
		Trees: trees,
	}

	variables, err := DefaultMakeVariables(pkg)
	if err != nil {
		t.Fatalf("%v", err)
	}

	expectedList := []string{
		"ARCH=abc",
		// because CC and CXX are loaded from toolchain_env, the arch will be
		// arch from the file and not the argument to DefaultMakeVariables
		"CC=toolchain/bin/x86_64-cros-linux-gnu-clang",
		"CXX=toolchain/bin/x86_64-cros-linux-gnu-clang++",
		"LD=toolchain/bin/abc-cros-linux-gnu-ld.lld",
		"STRIP=toolchain/bin/llvm-strip",
		"OBJCOPY=toolchain/bin/llvm-objcopy",
		"HOSTCC=abc-pc-linux-gnu-clang",
		"HOSTCXX=abc-pc-linux-gnu-clang++",
		"HOSTLD=abc-pc-linux-gnu-clang",
	}
	sort.Strings(expectedList)
	expected := strings.Join(expectedList, " ")

	diff := cmp.Diff(expected, variables)
	if diff != "" {
		t.Fatalf("default variables did not match expected\ndiff: %s", diff)
	}
}

func TestApplyPatch(t *testing.T) {
	buildDir := t.TempDir()
	if err := fs.CopyDir("testdata/source-tree/mymodule-1.0", buildDir, 0777); err != nil {
		t.Fatalf("%v", err)
	}

	patchPath := path.Join(buildDir, "patches", "a.patch")
	if err := ApplyPatch(buildDir, patchPath); err != nil {
		t.Fatalf("%v", err)
	}

	contents, err := os.ReadFile(path.Join(buildDir, "mymodule.c"))
	if err != nil {
		t.Fatalf("%v", err)
	}
	text := string(contents)
	if !strings.Contains(text, "patched") {
		t.Fatalf("expected mymodule.c to have comment `//patched` after patch is applied")
	}
}

func TestInstallBuildDependencies(t *testing.T) {
	downloader := kernel.FakeDownloader{}
	ctx := context.Background()
	targetDir := t.TempDir()
	defer os.RemoveAll(targetDir)

	err := installBuildDependencies(ctx, &downloader, targetDir)
	if err != nil {
		t.Errorf("failed to install build dependencies headers: %v", err)
	}
	if !kernel.KernelHeadersInstalled(targetDir) {
		t.Errorf("expected headers to be installed")
	}
	if !kernel.CompilerToolchainInstalled(targetDir) {
		t.Errorf("expected compiler toolchain to be installed")
	}
}
