package builder

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"cloud.google.com/go/storage"
	"cos.googlesource.com/cos/tools.git/src/pkg/cos"
	"cos.googlesource.com/cos/tools.git/src/pkg/gpuconfig"
	"cos.googlesource.com/cos/tools.git/src/pkg/utils"
)

const (
	linkerLocation        = "/bin/ld"
	patchDir              = "/build/patches"
	installDirTemplate    = "/install/%s"
	defaultFilePermission = 0755
	kernelSrcTemplate     = "usr/src/linux-headers-*"
)

func kernelSrcDirectory(dirName string) string {
	files, err := filepath.Glob(filepath.Join(dirName, kernelSrcTemplate))
	if err != nil || len(files) != 1 {
		return ""
	}
	return files[0]
}

func nvidiaInstallerBuildCommand(dirName, runfile string, config gpuconfig.GPUPrecompilationConfig) *exec.Cmd {
	cmd := exec.Command(filepath.Join(dirName, runfile), "--kernel-source-path="+kernelSrcDirectory(dirName), "--add-this-kernel", "--no-install-compat32-libs", "--silent", "--accept-license")
	cmd.Dir = dirName
	return cmd
}

func nvidiaInstallerPatchCommand(dirName, runfile, patchDir, patchfile string) *exec.Cmd {
	cmd := exec.Command(filepath.Join(dirName, runfile), "--apply-patch", filepath.Join(patchDir, patchfile))
	cmd.Dir = dirName
	return cmd
}

func BuildPrecompiledDriver(ctx context.Context, client *storage.Client, config gpuconfig.GPUPrecompilationConfig) (string, string, error) {
	var err error
	dirName := fmt.Sprintf(installDirTemplate, config.Version)
	if err = os.MkdirAll(dirName, defaultFilePermission); err != nil {
		return "", "", fmt.Errorf("failed to create installation dir: %v", err)
	}
	downloader := gpuconfig.NewGPUArtifactsDownloader(client, config)
	// download NVIDIA runfile
	var nvidiaInstaller string
	if nvidiaInstaller, err = downloader.DownloadNVIDIARunfile(ctx, dirName); err != nil {
		return "", "", fmt.Errorf("failed to download NVIDIA runfile: %v", err)
	}
	// install kernel headers and toolchain
	// sets SYSROOT and PATH env vars
	if err = cos.InstallCrossToolchain(ctx, downloader, dirName); err != nil {
		return "", "", fmt.Errorf("failed to install toolchain: %v", err)
	}
	// set CC CXX env vars from toolchain_env
	if err = cos.SetCompilationEnv(ctx, downloader); err != nil {
		return "", "", fmt.Errorf("failed to set compilation env vars: %v", err)
	}
	// create symlink to ld - required by NVIDIA driver package
	if err = cos.ForceSymlinkLinker(filepath.Join(dirName, linkerLocation)); err != nil {
		return "", "", fmt.Errorf("failed to create symlink to COS linker: %v", err)
	}
	cc := os.Getenv("CC")
	if cc == "" {
		return "", "", fmt.Errorf("failed to find CC in env")
	} else {
		// create a wrapper removing -Werror=strict-prototypes from the CC command line.
		if err = cos.AddCCWrapperToPath(dirName, dirName, cc); err != nil {
			return "", "", fmt.Errorf("failed to create CC wrapper: %v", err)
		}
	}
	// run NVIDIA driver package
	if err = os.Chmod(filepath.Join(dirName, nvidiaInstaller), defaultFilePermission); err != nil {
		return "", "", err
	}

	// TODO: add driver patches arg to pb.COSGPUBuildRequest
	// hardcoded list for known patches for now.
	patches := patchesForDriverBuild(config)
	for _, patch := range patches {
		cmd := nvidiaInstallerPatchCommand(dirName, nvidiaInstaller, patchDir, patch)
		if err := utils.RunCommandAndLogOutput(cmd, false); err != nil {
			return "", "", fmt.Errorf("error applying provided patch to NVIDIA driver package: %v", err)
		}
		patchedInstaller := strings.Split(nvidiaInstaller, ".run")[0] + "-custom.run"
		if err := os.Rename(filepath.Join(dirName, patchedInstaller), filepath.Join(dirName, nvidiaInstaller)); err != nil {
			return "", "", fmt.Errorf("error moving patched NVIDIA driver package: %v", err)
		}
	}

	cmd := nvidiaInstallerBuildCommand(dirName, nvidiaInstaller, config)
	if err = utils.RunCommandAndLogOutput(cmd, false); err != nil {
		return "", "", fmt.Errorf("error running NVIDIA driver installation package: %v", err)
	}

	outputFileName := strings.Split(nvidiaInstaller, ".run")[0] + "-custom.run"
	return dirName, outputFileName, nil
}

func patchesForDriverBuild(config gpuconfig.GPUPrecompilationConfig) []string {
	pfnAffectedDriverVersions := []string{"470.199.02", "470.223.02", "525.125.06", "525.147.05", "535.104.05", "535.104.12", "535.129.03", "535.154.05"}
	pfnAffectedMilestones := []string{"97", "101", "105"}
	var patches []string
	if utils.StringSliceContains(pfnAffectedDriverVersions, config.DriverVersion) && utils.StringSliceContains(pfnAffectedMilestones, config.Milestone) {
		var kernelVersionDot string
		if config.Milestone == "97" {
			kernelVersionDot = "5.10"
		} else {
			kernelVersionDot = "5.15"
		}
		majorDriverVersion := strings.Split(config.DriverVersion, ".")[0]
		patchFile := fmt.Sprintf("nvidia-drivers-%s-%s-gpl-pfn_valid.patch", majorDriverVersion, kernelVersionDot)
		patches = append(patches, patchFile)
	}
	return patches
}
