package cli

import (
	"os"
	"syscall"
	"unsafe"
)

// IsTerminalFile returns true if f is a terminal.
func IsTerminalFile(f *os.File) bool {
	if f == nil {
		return false
	}

	var termios syscall.Termios
	return ioctlFunc(
		f.Fd(),
		uintptr(syscall.TCGETS),
		unsafe.Pointer(&termios),
	) == 0
}

// TerminalWidth returns the width of terminal f in columns.
// It returns 0 if f is nil or the width cannot be determined.
func TerminalWidth(f *os.File) int {
	if f == nil {
		return 0
	}

	var ws struct{ row, col, xpixel, ypixel uint16 }
	if ioctlFunc(f.Fd(), uintptr(syscall.TIOCGWINSZ), unsafe.Pointer(&ws)) != 0 {
		return 0
	}
	return int(ws.col)
}

// To be overridden in tests.
var ioctlFunc = func(fd, req uintptr, arg unsafe.Pointer) syscall.Errno {
	_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, req, uintptr(arg))
	return errno
}
