// Copyright 2020 The Chromium OS 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 arc

import (
	"context"
	"fmt"
	"io/ioutil"
	"regexp"
	"runtime"
	"strings"

	"github.com/shirou/gopsutil/process"

	"chromiumos/tast/common/testexec"
	"chromiumos/tast/errors"
	"chromiumos/tast/local/arc"
	"chromiumos/tast/local/bundles/cros/arc/cpuset"
	"chromiumos/tast/shutil"
	"chromiumos/tast/testing"
)

func init() {
	testing.AddTest(&testing.Test{
		Func: CPUSet,
		Desc: "Verifies cpuset",
		Contacts: []string{
			"risan@chromium.org",
			"arc-core@google.com",
			"arc-storage@google.com",
			"hidehiko@chromium.org", // Tast port author.
		},
		SoftwareDeps: []string{
			"chrome",
		},
		Attr:    []string{"group:mainline"},
		Fixture: "arcBooted",
		Params: []testing.Param{{
			ExtraSoftwareDeps: []string{"android_p"},
		}, {
			Name:              "vm",
			ExtraSoftwareDeps: []string{"android_vm"},
		}},
	})
}

// getInitPIDs returns all PIDs corresponding to ARC init processes.
// TODO (hidehiko@): merge this and InitPID()
func getInitPIDs() ([]int, error) {
	ver, err := arc.SDKVersion()
	if err != nil {
		return nil, err
	}

	// The path to the ARC init executable.
	var initExecPath = "/init"
	if ver >= arc.SDKQ {
		initExecPath = "/system/bin/init"
	}

	all, err := process.Pids()
	if err != nil {
		return nil, err
	}

	var pids []int
	for _, pid := range all {
		proc, err := process.NewProcess(pid)
		if err != nil {
			// Assume that the process exited.
			continue
		}
		if exe, err := proc.Exe(); err == nil && exe == initExecPath {
			if username, err := proc.Username(); err == nil && username == "android-root" {
				pids = append(pids, int(pid))
			}
		}
	}
	return pids, nil
}

// getRootPID returns the PID of the root ARC init process.
func getRootPID() (int, error) {
	pids, err := getInitPIDs()
	if err != nil {
		return -1, err
	}

	pm := make(map[int]struct{}, len(pids))
	for _, pid := range pids {
		pm[pid] = struct{}{}
	}
	for _, pid := range pids {
		// If we see errors, assume that the process exited.
		proc, err := process.NewProcess(int32(pid))
		if err != nil {
			continue
		}
		ppid, err := proc.Ppid()
		if err != nil || ppid <= 0 {
			continue
		}
		if _, ok := pm[int(ppid)]; !ok {
			return pid, nil
		}
	}
	return -1, errors.New("root not found")
}

// Intel does not have any 'CPU part' line. ARM does, and when it's
// big.LITTLE, it has two different CPU parts (e.g. 0xd03 and 0xd09).
var cpuPartRE = regexp.MustCompile(`^CPU part\s+:\s+(0x[0-9a-f]+)$`)

// isHeterogeneousCores returns true if cores are heterogeneous ones
// such as ARM's big.LITTLE.
func isHeterogeneousCores(ctx context.Context) (bool, error) {
	if arch := runtime.GOARCH; arch != "arm" && arch != "arm64" {
		return false, nil
	}

	out, err := ioutil.ReadFile("/proc/cpuinfo")

	if err != nil {
		return false, errors.Wrap(err, "failed to read cpuinfo")
	}
	lines := strings.Split(string(out), "\n")

	var lastCPUPart string
	for _, line := range lines {
		matches := cpuPartRE.FindAllStringSubmatch(strings.TrimSpace(line), -1)
		if matches == nil {
			continue
		}
		cpuPart := matches[0][1]
		if lastCPUPart == "" {
			lastCPUPart = cpuPart
			continue
		}
		if lastCPUPart != cpuPart {
			testing.ContextLog(ctx, "Detected heterogeneous cores")
			return true, nil
		}
	}
	if lastCPUPart == "" {
		return false, errors.New("no CPU part information found")
	}
	return false, nil
}

func readCPUSetInfo(ctx context.Context, t string) (string, []byte, error) {
	isVMEnabled, err := arc.VMEnabled()
	if err != nil {
		return "", nil, err
	}
	if isVMEnabled {
		path := fmt.Sprintf("/proc/1/root/dev/cpuset/%s/effective_cpus", t)
		out, err := testexec.CommandContext(ctx, "android-sh", "-c", fmt.Sprintf("cat %s", shutil.Escape(path))).Output(testexec.DumpLogOnError)
		return path, out, err
	}

	initPID, err := getRootPID()
	if err != nil {
		return "", nil, err
	}
	path := fmt.Sprintf("/proc/%d/root/dev/cpuset/%s/effective_cpus", initPID, t)
	// cgroup pseudo file cannot be "adb pull"ed. Additionally, it is not
	// accessible via adb shell user in P. Access by procfs instead.
	out, err := ioutil.ReadFile(path)
	return path, out, err
}

func CPUSet(ctx context.Context, s *testing.State) {
	s.Log("Running testCPUSet")

	// Verify that /dev/cpuset is properly set up.
	types := []string{"foreground", "background", "system-background", "top-app", "restricted"}
	numOtherCores := 0

	for _, t := range types {
		// cgroup pseudo file cannot be "adb pull"ed. Additionally, it is not
		// accessible via adb shell user in P. Access by procfs instead.
		path, out, err := readCPUSetInfo(ctx, t)

		if err != nil {
			s.Errorf("Failed to read %s: %v", path, err)
			continue
		}
		val := strings.TrimSpace(string(out))
		cpusInUse, err := cpuset.Parse(ctx, val)
		if err != nil {
			s.Errorf("Failed to parse %s: %v", path, err)
			continue
		}

		if t == "foreground" || t == "top-app" {
			// Even after full boot, these processes should be able
			// to use all CPU cores.
			if len(cpusInUse) != runtime.NumCPU() {
				s.Errorf("Unexpected CPU setting %q for %s: got %d CPUs, want %d CPUs", val, path,
					len(cpusInUse), runtime.NumCPU())
			}
		} else {
			// Other processes should not.
			if len(cpusInUse) == runtime.NumCPU() {
				s.Errorf("Unexpected CPU setting %q for %s: should not be %d CPUs", val, path,
					runtime.NumCPU())
			}
			numOtherCores += len(cpusInUse)
		}
	}

	heterogeneousCores, err := isHeterogeneousCores(ctx)
	if err != nil {
		s.Error("Failed to determine core type: ", err)
		return
	}
	if heterogeneousCores {
		// The cpuset settings done in init.{cheets,bertha}.rc work fine
		// for homogeneous systems, but heterogeneous systems require
		// their own init.cpusets.rc to properly set up non-foreground
		// cpusets. Verify that init.cpusets.rc exists on heterogeneous
		// systems.
		s.Log("Running testCPUSet (for boards with heterogeneous cores)")
		if numOtherCores == 3 {
			s.Error("Unexpected CPU setting; found heterogeneous cores but lacks proper init.cpusets.rc file")
		}
	}
}
