/*
   Copyright The containerd 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.
*/

// Package cap provides Linux capability utility
package cap

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

// FromNumber returns a cap string like "CAP_SYS_ADMIN"
// that corresponds to the given number like 21.
//
// FromNumber returns an empty string for unknown cap number.
func FromNumber(num int) string {
	if num < 0 || num > len(capsLatest)-1 {
		return ""
	}
	return capsLatest[num]
}

// FromBitmap parses an uint64 bitmap into string slice like
// []{"CAP_SYS_ADMIN", ...}.
//
// Unknown cap numbers are returned as []int.
func FromBitmap(v uint64) ([]string, []int) {
	var (
		res     []string
		unknown []int
	)
	for i := 0; i <= 63; i++ {
		if b := (v >> i) & 0x1; b == 0x1 {
			if s := FromNumber(i); s != "" {
				res = append(res, s)
			} else {
				unknown = append(unknown, i)
			}
		}
	}
	return res, unknown
}

// Type is the type of capability
type Type int

const (
	// Effective is CapEff
	Effective Type = 1 << iota
	// Permitted is CapPrm
	Permitted
	// Inheritable is CapInh
	Inheritable
	// Bounding is CapBnd
	Bounding
	// Ambient is CapAmb
	Ambient
)

// ParseProcPIDStatus returns uint64 bitmap value from /proc/<PID>/status file
func ParseProcPIDStatus(r io.Reader) (map[Type]uint64, error) {
	res := make(map[Type]uint64)
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		line := scanner.Text()
		k, v, ok := strings.Cut(line, ":")
		if !ok {
			continue
		}
		k = strings.TrimSpace(k)
		switch k {
		case "CapInh", "CapPrm", "CapEff", "CapBnd", "CapAmb":
			ui64, err := strconv.ParseUint(strings.TrimSpace(v), 16, 64)
			if err != nil {
				return nil, fmt.Errorf("failed to parse line %q", line)
			}
			switch k {
			case "CapInh":
				res[Inheritable] = ui64
			case "CapPrm":
				res[Permitted] = ui64
			case "CapEff":
				res[Effective] = ui64
			case "CapBnd":
				res[Bounding] = ui64
			case "CapAmb":
				res[Ambient] = ui64
			}
		}
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}
	return res, nil
}

// Current returns the list of the effective and the known caps of
// the current process.
//
// The result is like []string{"CAP_SYS_ADMIN", ...}.
func Current() ([]string, error) {
	f, err := os.Open("/proc/self/status")
	if err != nil {
		return nil, err
	}
	defer f.Close()
	caps, err := ParseProcPIDStatus(f)
	if err != nil {
		return nil, err
	}
	capEff := caps[Effective]
	names, _ := FromBitmap(capEff)
	return names, nil
}

var (
	// caps35 is the caps of kernel 3.5 (37 entries)
	caps35 = []string{
		"CAP_CHOWN",            // 2.2
		"CAP_DAC_OVERRIDE",     // 2.2
		"CAP_DAC_READ_SEARCH",  // 2.2
		"CAP_FOWNER",           // 2.2
		"CAP_FSETID",           // 2.2
		"CAP_KILL",             // 2.2
		"CAP_SETGID",           // 2.2
		"CAP_SETUID",           // 2.2
		"CAP_SETPCAP",          // 2.2
		"CAP_LINUX_IMMUTABLE",  // 2.2
		"CAP_NET_BIND_SERVICE", // 2.2
		"CAP_NET_BROADCAST",    // 2.2
		"CAP_NET_ADMIN",        // 2.2
		"CAP_NET_RAW",          // 2.2
		"CAP_IPC_LOCK",         // 2.2
		"CAP_IPC_OWNER",        // 2.2
		"CAP_SYS_MODULE",       // 2.2
		"CAP_SYS_RAWIO",        // 2.2
		"CAP_SYS_CHROOT",       // 2.2
		"CAP_SYS_PTRACE",       // 2.2
		"CAP_SYS_PACCT",        // 2.2
		"CAP_SYS_ADMIN",        // 2.2
		"CAP_SYS_BOOT",         // 2.2
		"CAP_SYS_NICE",         // 2.2
		"CAP_SYS_RESOURCE",     // 2.2
		"CAP_SYS_TIME",         // 2.2
		"CAP_SYS_TTY_CONFIG",   // 2.2
		"CAP_MKNOD",            // 2.4
		"CAP_LEASE",            // 2.4
		"CAP_AUDIT_WRITE",      // 2.6.11
		"CAP_AUDIT_CONTROL",    // 2.6.11
		"CAP_SETFCAP",          // 2.6.24
		"CAP_MAC_OVERRIDE",     // 2.6.25
		"CAP_MAC_ADMIN",        // 2.6.25
		"CAP_SYSLOG",           // 2.6.37
		"CAP_WAKE_ALARM",       // 3.0
		"CAP_BLOCK_SUSPEND",    // 3.5
	}
	// caps316 is the caps of kernel 3.16 (38 entries)
	caps316 = append(caps35, "CAP_AUDIT_READ")
	// caps58 is the caps of kernel 5.8 (40 entries)
	caps58 = append(caps316, []string{"CAP_PERFMON", "CAP_BPF"}...)
	// caps59 is the caps of kernel 5.9 (41 entries)
	caps59     = append(caps58, "CAP_CHECKPOINT_RESTORE")
	capsLatest = caps59
)

// Known returns the known cap strings of the latest kernel.
// The current latest kernel is 5.9.
func Known() []string {
	return capsLatest
}
