package libcontainer

import (
	"errors"
	"fmt"
	"os"
	"runtime"

	"github.com/containerd/console"
	"golang.org/x/sys/unix"

	"github.com/opencontainers/runc/internal/linux"
	"github.com/opencontainers/runc/internal/pathrs"
	"github.com/opencontainers/runc/internal/sys"
	"github.com/opencontainers/runc/libcontainer/utils"
)

// checkPtmxHandle checks that the given file handle points to a real
// /dev/pts/ptmx device inode on a real devpts mount. We cannot (trivially)
// check that it is *the* /dev/pts for the container itself, but this is good
// enough.
func checkPtmxHandle(ptmx *os.File) error {
	//nolint:revive,staticcheck,nolintlint // ignore "don't use ALL_CAPS" warning // nolintlint is needed to work around the different lint configs
	const (
		PTMX_MAJOR = 5 // from TTYAUX_MAJOR in <linux/major.h>
		PTMX_MINOR = 2 // from mknod_ptmx in fs/devpts/inode.c
		PTMX_INO   = 2 // from mknod_ptmx in fs/devpts/inode.c
	)
	return sys.VerifyInode(ptmx, func(stat *unix.Stat_t, statfs *unix.Statfs_t) error {
		if statfs.Type != unix.DEVPTS_SUPER_MAGIC {
			return fmt.Errorf("ptmx handle is not on a real devpts mount: super magic is %#x", statfs.Type)
		}
		if stat.Ino != PTMX_INO {
			return fmt.Errorf("ptmx handle has wrong inode number: %v", stat.Ino)
		}
		if stat.Mode&unix.S_IFMT != unix.S_IFCHR || stat.Rdev != unix.Mkdev(PTMX_MAJOR, PTMX_MINOR) {
			return fmt.Errorf("ptmx handle is not a real char ptmx device: ftype %#x %d:%d",
				stat.Mode&unix.S_IFMT, unix.Major(stat.Rdev), unix.Minor(stat.Rdev))
		}
		return nil
	})
}

func isPtyNoIoctlError(err error) bool {
	// The kernel converts -ENOIOCTLCMD to -ENOTTY automatically, but handle
	// -EINVAL just in case (which some drivers do, include pty).
	return errors.Is(err, unix.EINVAL) || errors.Is(err, unix.ENOTTY)
}

func getPtyPeer(pty console.Console, unsafePeerPath string, flags int) (*os.File, error) {
	peer, err := linux.GetPtyPeer(pty.Fd(), unsafePeerPath, flags)
	if err == nil || !isPtyNoIoctlError(err) {
		return peer, err
	}

	// On pre-TIOCGPTPEER kernels (Linux < 4.13), we need to fallback to using
	// the /dev/pts/$n path generated using TIOCGPTN. We can do some validation
	// that the inode is correct because the Unix-98 pty has a consistent
	// numbering scheme for the device number of the peer.

	peerNum, err := unix.IoctlGetUint32(int(pty.Fd()), unix.TIOCGPTN)
	if err != nil {
		return nil, fmt.Errorf("get peer number of pty: %w", err)
	}
	//nolint:revive,staticcheck,nolintlint // ignore "don't use ALL_CAPS" warning // nolintlint is needed to work around the different lint configs
	const (
		UNIX98_PTY_SLAVE_MAJOR = 136 // from <linux/major.h>
	)
	wantPeerDev := unix.Mkdev(UNIX98_PTY_SLAVE_MAJOR, peerNum)

	// Use O_PATH to avoid opening a bad inode before we validate it.
	peerHandle, err := os.OpenFile(unsafePeerPath, unix.O_PATH|unix.O_CLOEXEC, 0)
	if err != nil {
		return nil, err
	}
	defer peerHandle.Close()

	if err := sys.VerifyInode(peerHandle, func(stat *unix.Stat_t, statfs *unix.Statfs_t) error {
		if statfs.Type != unix.DEVPTS_SUPER_MAGIC {
			return fmt.Errorf("pty peer handle is not on a real devpts mount: super magic is %#x", statfs.Type)
		}
		if stat.Mode&unix.S_IFMT != unix.S_IFCHR || stat.Rdev != wantPeerDev {
			return fmt.Errorf("pty peer handle is not the real char device for pty %d: ftype %#x %d:%d",
				peerNum, stat.Mode&unix.S_IFMT, unix.Major(stat.Rdev), unix.Minor(stat.Rdev))
		}
		return nil
	}); err != nil {
		return nil, err
	}

	return pathrs.Reopen(peerHandle, flags)
}

// safeAllocPty returns a new (ptmx, peer pty) allocation for use inside a
// container.
func safeAllocPty() (pty console.Console, peer *os.File, Err error) {
	// TODO: Use openat2(RESOLVE_NO_SYMLINKS|RESOLVE_NO_XDEV).
	ptmxHandle, err := os.OpenFile("/dev/pts/ptmx", unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0)
	if err != nil {
		return nil, nil, err
	}
	defer ptmxHandle.Close()

	if err := checkPtmxHandle(ptmxHandle); err != nil {
		return nil, nil, fmt.Errorf("verify ptmx handle: %w", err)
	}

	ptyFile, err := pathrs.Reopen(ptmxHandle, unix.O_RDWR|unix.O_NOCTTY)
	if err != nil {
		return nil, nil, fmt.Errorf("reopen ptmx to get new pty pair: %w", err)
	}
	// On success, the ownership is transferred to pty.
	defer func() {
		if Err != nil {
			_ = ptyFile.Close()
		}
	}()

	pty, unsafePeerPath, err := console.NewPtyFromFile(ptyFile)
	if err != nil {
		return nil, nil, err
	}
	defer func() {
		if Err != nil {
			_ = pty.Close()
		}
	}()

	peer, err = getPtyPeer(pty, unsafePeerPath, unix.O_RDWR|unix.O_NOCTTY)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to get peer end of newly-allocated console: %w", err)
	}
	return pty, peer, nil
}

// mountConsole bind-mounts the provided pty on top of /dev/console so programs
// that operate on /dev/console operate on the correct container pty.
func mountConsole(peerPty *os.File) error {
	console, err := os.OpenFile("/dev/console", unix.O_NOFOLLOW|unix.O_CREAT|unix.O_CLOEXEC, 0o666)
	if err != nil {
		return fmt.Errorf("create /dev/console mount target: %w", err)
	}
	defer console.Close()

	dstFd, closer := utils.ProcThreadSelfFd(console.Fd())
	defer closer()

	mntSrc := &mountSource{
		Type: mountSourcePlain,
		file: peerPty,
	}
	return mountViaFds(peerPty.Name(), mntSrc, "/dev/console", dstFd, "bind", unix.MS_BIND, "")
}

// dupStdio replaces stdio with the given peerPty.
func dupStdio(peerPty *os.File) error {
	for _, i := range []int{0, 1, 2} {
		if err := unix.Dup3(int(peerPty.Fd()), i, 0); err != nil {
			return err
		}
	}
	runtime.KeepAlive(peerPty)
	return nil
}
