package seccomp // import "github.com/docker/docker/profiles/seccomp"

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	"github.com/opencontainers/runtime-spec/specs-go"
)

// Seccomp represents the config for a seccomp profile for syscall restriction.
type Seccomp struct {
	DefaultAction specs.LinuxSeccompAction `json:"defaultAction"`
	// Architectures is kept to maintain backward compatibility with the old
	// seccomp profile.
	Architectures []specs.Arch   `json:"architectures,omitempty"`
	ArchMap       []Architecture `json:"archMap,omitempty"`
	Syscalls      []*Syscall     `json:"syscalls"`
}

// Architecture is used to represent a specific architecture
// and its sub-architectures
type Architecture struct {
	Arch      specs.Arch   `json:"architecture"`
	SubArches []specs.Arch `json:"subArchitectures"`
}

// Filter is used to conditionally apply Seccomp rules
type Filter struct {
	Caps   []string `json:"caps,omitempty"`
	Arches []string `json:"arches,omitempty"`

	// MinKernel describes the minimum kernel version the rule must be applied
	// on, in the format "<kernel version>.<major revision>" (e.g. "3.12").
	//
	// When matching the kernel version of the host, minor revisions, and distro-
	// specific suffixes are ignored, which means that "3.12.25-gentoo", "3.12-1-amd64",
	// "3.12", and "3.12-rc5" are considered equal (kernel 3, major revision 12).
	MinKernel *KernelVersion `json:"minKernel,omitempty"`
}

// Syscall is used to match a group of syscalls in Seccomp
type Syscall struct {
	Name     string                   `json:"name,omitempty"`
	Names    []string                 `json:"names,omitempty"`
	Action   specs.LinuxSeccompAction `json:"action"`
	Args     []*specs.LinuxSeccompArg `json:"args"`
	Comment  string                   `json:"comment"`
	Includes Filter                   `json:"includes"`
	Excludes Filter                   `json:"excludes"`
}

// KernelVersion holds information about the kernel.
type KernelVersion struct {
	Kernel uint64 // Version of the Kernel (i.e., the "4" in "4.1.2-generic")
	Major  uint64 // Major revision of the Kernel (i.e., the "1" in "4.1.2-generic")
}

// String implements fmt.Stringer for KernelVersion
func (k *KernelVersion) String() string {
	if k.Kernel > 0 || k.Major > 0 {
		return fmt.Sprintf("%d.%d", k.Kernel, k.Major)
	}
	return ""
}

// MarshalJSON implements json.Unmarshaler for KernelVersion
func (k *KernelVersion) MarshalJSON() ([]byte, error) {
	return json.Marshal(k.String())
}

// UnmarshalJSON implements json.Marshaler for KernelVersion
func (k *KernelVersion) UnmarshalJSON(version []byte) error {
	var (
		ver string
		err error
	)

	// make sure we have a string
	if err = json.Unmarshal(version, &ver); err != nil {
		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": %v`, string(version), err)
	}
	if ver == "" {
		return nil
	}
	parts := strings.SplitN(ver, ".", 3)
	if len(parts) != 2 {
		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>"`, string(version))
	}
	if k.Kernel, err = strconv.ParseUint(parts[0], 10, 8); err != nil {
		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": %v`, string(version), err)
	}
	if k.Major, err = strconv.ParseUint(parts[1], 10, 8); err != nil {
		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": %v`, string(version), err)
	}
	if k.Kernel == 0 && k.Major == 0 {
		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": version cannot be 0.0`, string(version))
	}
	return nil
}
