// Copyright 2019 The gVisor Authors.
//
// 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.

//go:build arm64
// +build arm64

package cpuid

import (
	"encoding/binary"
	"io/ioutil"
	"strconv"
	"strings"

	"gvisor.dev/gvisor/pkg/log"
)

// hostFeatureSet is initialized at startup.
//
// This is copied for HostFeatureSet, below.
var hostFeatureSet FeatureSet

// HostFeatureSet returns a copy of the host FeatureSet.
func HostFeatureSet() FeatureSet {
	return hostFeatureSet
}

// Fixed returns the same feature set.
func (fs FeatureSet) Fixed() FeatureSet {
	return fs
}

// Reads CPU information from host /proc/cpuinfo.
//
// Must run before syscall filter installation. This value is used to create
// the fake /proc/cpuinfo from a FeatureSet.
func initCPUInfo() {
	cpuinfob, err := ioutil.ReadFile("/proc/cpuinfo")
	if err != nil {
		// Leave everything at 0, nothing can be done.
		log.Warningf("Could not read /proc/cpuinfo: %v", err)
		return
	}
	cpuinfo := string(cpuinfob)

	// We get the value straight from host /proc/cpuinfo.
	for _, line := range strings.Split(cpuinfo, "\n") {
		switch {
		case strings.Contains(line, "BogoMIPS"):
			splitMHz := strings.Split(line, ":")
			if len(splitMHz) < 2 {
				log.Warningf("Could not read /proc/cpuinfo: malformed BogoMIPS")
				break
			}

			// If there was a problem, leave cpuFreqMHz as 0.
			var err error
			hostFeatureSet.cpuFreqMHz, err = strconv.ParseFloat(strings.TrimSpace(splitMHz[1]), 64)
			if err != nil {
				hostFeatureSet.cpuFreqMHz = 0.0
				log.Warningf("Could not parse BogoMIPS value %v: %v", splitMHz[1], err)
			}
		case strings.Contains(line, "CPU implementer"):
			splitImpl := strings.Split(line, ":")
			if len(splitImpl) < 2 {
				log.Warningf("Could not read /proc/cpuinfo: malformed CPU implementer")
				break
			}

			// If there was a problem, leave cpuImplHex as 0.
			var err error
			hostFeatureSet.cpuImplHex, err = strconv.ParseUint(strings.TrimSpace(splitImpl[1]), 0, 64)
			if err != nil {
				hostFeatureSet.cpuImplHex = 0
				log.Warningf("Could not parse CPU implementer value %v: %v", splitImpl[1], err)
			}
		case strings.Contains(line, "CPU architecture"):
			splitArch := strings.Split(line, ":")
			if len(splitArch) < 2 {
				log.Warningf("Could not read /proc/cpuinfo: malformed CPU architecture")
				break
			}

			// If there was a problem, leave cpuArchDec as 0.
			var err error
			hostFeatureSet.cpuArchDec, err = strconv.ParseUint(strings.TrimSpace(splitArch[1]), 0, 64)
			if err != nil {
				hostFeatureSet.cpuArchDec = 0
				log.Warningf("Could not parse CPU architecture value %v: %v", splitArch[1], err)
			}
		case strings.Contains(line, "CPU variant"):
			splitVar := strings.Split(line, ":")
			if len(splitVar) < 2 {
				log.Warningf("Could not read /proc/cpuinfo: malformed CPU variant")
				break
			}

			// If there was a problem, leave cpuVarHex as 0.
			var err error
			hostFeatureSet.cpuVarHex, err = strconv.ParseUint(strings.TrimSpace(splitVar[1]), 0, 64)
			if err != nil {
				hostFeatureSet.cpuVarHex = 0
				log.Warningf("Could not parse CPU variant value %v: %v", splitVar[1], err)
			}
		case strings.Contains(line, "CPU part"):
			splitPart := strings.Split(line, ":")
			if len(splitPart) < 2 {
				log.Warningf("Could not read /proc/cpuinfo: malformed CPU part")
				break
			}

			// If there was a problem, leave cpuPartHex as 0.
			var err error
			hostFeatureSet.cpuPartHex, err = strconv.ParseUint(strings.TrimSpace(splitPart[1]), 0, 64)
			if err != nil {
				hostFeatureSet.cpuPartHex = 0
				log.Warningf("Could not parse CPU part value %v: %v", splitPart[1], err)
			}
		case strings.Contains(line, "CPU revision"):
			splitRev := strings.Split(line, ":")
			if len(splitRev) < 2 {
				log.Warningf("Could not read /proc/cpuinfo: malformed CPU revision")
				break
			}

			// If there was a problem, leave cpuRevDec as 0.
			var err error
			hostFeatureSet.cpuRevDec, err = strconv.ParseUint(strings.TrimSpace(splitRev[1]), 0, 64)
			if err != nil {
				hostFeatureSet.cpuRevDec = 0
				log.Warningf("Could not parse CPU revision value %v: %v", splitRev[1], err)
			}
		}
	}
}

// The auxiliary vector of a process on the Linux system can be read
// from /proc/self/auxv, and tags and values are stored as 8-bytes
// decimal key-value pairs on the 64-bit system.
//
// $ od -t d8 /proc/self/auxv
//  0000000                   33      140734615224320
//  0000020                   16           3219913727
//  0000040                    6                 4096
//  0000060                   17                  100
//  0000100                    3       94665627353152
//  0000120                    4                   56
//  0000140                    5                    9
//  0000160                    7      140425502162944
//  0000200                    8                    0
//  0000220                    9       94665627365760
//  0000240                   11                 1000
//  0000260                   12                 1000
//  0000300                   13                 1000
//  0000320                   14                 1000
//  0000340                   23                    0
//  0000360                   25      140734614619513
//  0000400                   26                    0
//  0000420                   31      140734614626284
//  0000440                   15      140734614619529
//  0000460                    0                    0
func initHwCap() {
	auxv, err := ioutil.ReadFile("/proc/self/auxv")
	if err != nil {
		log.Warningf("Could not read /proc/self/auxv: %v", err)
		return
	}

	const _AT_HWCAP = 16 // hardware capability bit vector.
	l := len(auxv) / 16
	for i := 0; i < l; i++ {
		tag := binary.LittleEndian.Uint64(auxv[i*16:])
		val := binary.LittleEndian.Uint64(auxv[(i*16 + 8):])
		if tag == _AT_HWCAP {
			hostFeatureSet.hwCap = uint(val)
			break
		}
	}
}

func init() {
	initCPUInfo()
	initHwCap()
}
