package liner

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

var (
	kernel32 = syscall.NewLazyDLL("kernel32.dll")

	procGetStdHandle               = kernel32.NewProc("GetStdHandle")
	procReadConsoleInput           = kernel32.NewProc("ReadConsoleInputW")
	procGetConsoleMode             = kernel32.NewProc("GetConsoleMode")
	procSetConsoleMode             = kernel32.NewProc("SetConsoleMode")
	procSetConsoleCursorPosition   = kernel32.NewProc("SetConsoleCursorPosition")
	procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
	procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
)

// These names are from the Win32 api, so they use underscores (contrary to
// what golint suggests)
const (
	std_input_handle     = uint32(-10 & 0xFFFFFFFF)
	std_output_handle    = uint32(-11 & 0xFFFFFFFF)
	std_error_handle     = uint32(-12 & 0xFFFFFFFF)
	invalid_handle_value = ^uintptr(0)
)

type inputMode uint32

// State represents an open terminal
type State struct {
	commonState
	handle      syscall.Handle
	hOut        syscall.Handle
	origMode    inputMode
	defaultMode inputMode
	key         interface{}
	repeat      uint16
}

const (
	enableEchoInput      = 0x4
	enableInsertMode     = 0x20
	enableLineInput      = 0x2
	enableMouseInput     = 0x10
	enableProcessedInput = 0x1
	enableQuickEditMode  = 0x40
	enableWindowInput    = 0x8
)

// NewLiner initializes a new *State, and sets the terminal into raw mode. To
// restore the terminal to its previous state, call State.Close().
func NewLiner() *State {
	var s State
	hIn, _, _ := procGetStdHandle.Call(uintptr(std_input_handle))
	s.handle = syscall.Handle(hIn)
	hOut, _, _ := procGetStdHandle.Call(uintptr(std_output_handle))
	s.hOut = syscall.Handle(hOut)

	s.terminalSupported = true
	if m, err := TerminalMode(); err == nil {
		s.origMode = m.(inputMode)
		mode := s.origMode
		mode &^= enableEchoInput
		mode &^= enableInsertMode
		mode &^= enableLineInput
		mode &^= enableMouseInput
		mode |= enableWindowInput
		mode.ApplyMode()
	} else {
		s.inputRedirected = true
		s.r = bufio.NewReader(os.Stdin)
	}

	s.getColumns()
	s.outputRedirected = s.columns <= 0

	return &s
}

// These names are from the Win32 api, so they use underscores (contrary to
// what golint suggests)
const (
	focus_event              = 0x0010
	key_event                = 0x0001
	menu_event               = 0x0008
	mouse_event              = 0x0002
	window_buffer_size_event = 0x0004
)

type input_record struct {
	eventType uint16
	pad       uint16
	blob      [16]byte
}

type key_event_record struct {
	KeyDown         int32
	RepeatCount     uint16
	VirtualKeyCode  uint16
	VirtualScanCode uint16
	Char            int16
	ControlKeyState uint32
}

// These names are from the Win32 api, so they use underscores (contrary to
// what golint suggests)
const (
	vk_tab    = 0x09
	vk_prior  = 0x21
	vk_next   = 0x22
	vk_end    = 0x23
	vk_home   = 0x24
	vk_left   = 0x25
	vk_up     = 0x26
	vk_right  = 0x27
	vk_down   = 0x28
	vk_insert = 0x2d
	vk_delete = 0x2e
	vk_f1     = 0x70
	vk_f2     = 0x71
	vk_f3     = 0x72
	vk_f4     = 0x73
	vk_f5     = 0x74
	vk_f6     = 0x75
	vk_f7     = 0x76
	vk_f8     = 0x77
	vk_f9     = 0x78
	vk_f10    = 0x79
	vk_f11    = 0x7a
	vk_f12    = 0x7b
	bKey      = 0x42
	fKey      = 0x46
	yKey      = 0x59
)

const (
	shiftPressed     = 0x0010
	leftAltPressed   = 0x0002
	leftCtrlPressed  = 0x0008
	rightAltPressed  = 0x0001
	rightCtrlPressed = 0x0004

	modKeys = shiftPressed | leftAltPressed | rightAltPressed | leftCtrlPressed | rightCtrlPressed
)

func (s *State) readNext() (interface{}, error) {
	if s.repeat > 0 {
		s.repeat--
		return s.key, nil
	}

	var input input_record
	pbuf := uintptr(unsafe.Pointer(&input))
	var rv uint32
	prv := uintptr(unsafe.Pointer(&rv))

	for {
		ok, _, err := procReadConsoleInput.Call(uintptr(s.handle), pbuf, 1, prv)

		if ok == 0 {
			return nil, err
		}

		if input.eventType == window_buffer_size_event {
			xy := (*coord)(unsafe.Pointer(&input.blob[0]))
			s.columns = int(xy.x)
			return winch, nil
		}
		if input.eventType != key_event {
			continue
		}
		ke := (*key_event_record)(unsafe.Pointer(&input.blob[0]))
		if ke.KeyDown == 0 {
			continue
		}

		if ke.VirtualKeyCode == vk_tab && ke.ControlKeyState&modKeys == shiftPressed {
			s.key = shiftTab
		} else if ke.VirtualKeyCode == bKey && (ke.ControlKeyState&modKeys == leftAltPressed ||
			ke.ControlKeyState&modKeys == rightAltPressed) {
			s.key = altB
		} else if ke.VirtualKeyCode == fKey && (ke.ControlKeyState&modKeys == leftAltPressed ||
			ke.ControlKeyState&modKeys == rightAltPressed) {
			s.key = altF
		} else if ke.VirtualKeyCode == yKey && (ke.ControlKeyState&modKeys == leftAltPressed ||
			ke.ControlKeyState&modKeys == rightAltPressed) {
			s.key = altY
		} else if ke.Char > 0 {
			s.key = rune(ke.Char)
		} else {
			switch ke.VirtualKeyCode {
			case vk_prior:
				s.key = pageUp
			case vk_next:
				s.key = pageDown
			case vk_end:
				s.key = end
			case vk_home:
				s.key = home
			case vk_left:
				s.key = left
				if ke.ControlKeyState&(leftCtrlPressed|rightCtrlPressed) != 0 {
					if ke.ControlKeyState&modKeys == ke.ControlKeyState&(leftCtrlPressed|rightCtrlPressed) {
						s.key = wordLeft
					}
				}
			case vk_right:
				s.key = right
				if ke.ControlKeyState&(leftCtrlPressed|rightCtrlPressed) != 0 {
					if ke.ControlKeyState&modKeys == ke.ControlKeyState&(leftCtrlPressed|rightCtrlPressed) {
						s.key = wordRight
					}
				}
			case vk_up:
				s.key = up
			case vk_down:
				s.key = down
			case vk_insert:
				s.key = insert
			case vk_delete:
				s.key = del
			case vk_f1:
				s.key = f1
			case vk_f2:
				s.key = f2
			case vk_f3:
				s.key = f3
			case vk_f4:
				s.key = f4
			case vk_f5:
				s.key = f5
			case vk_f6:
				s.key = f6
			case vk_f7:
				s.key = f7
			case vk_f8:
				s.key = f8
			case vk_f9:
				s.key = f9
			case vk_f10:
				s.key = f10
			case vk_f11:
				s.key = f11
			case vk_f12:
				s.key = f12
			default:
				// Eat modifier keys
				// TODO: return Action(Unknown) if the key isn't a
				// modifier.
				continue
			}
		}

		if ke.RepeatCount > 1 {
			s.repeat = ke.RepeatCount - 1
		}
		return s.key, nil
	}
	return unknown, nil
}

// Close returns the terminal to its previous mode
func (s *State) Close() error {
	s.origMode.ApplyMode()
	return nil
}

func (s *State) startPrompt() {
	if m, err := TerminalMode(); err == nil {
		s.defaultMode = m.(inputMode)
		mode := s.defaultMode
		mode &^= enableProcessedInput
		mode.ApplyMode()
	}
}

func (s *State) restartPrompt() {
}

func (s *State) stopPrompt() {
	s.defaultMode.ApplyMode()
}

// TerminalSupported returns true because line editing is always
// supported on Windows.
func TerminalSupported() bool {
	return true
}

func (mode inputMode) ApplyMode() error {
	hIn, _, err := procGetStdHandle.Call(uintptr(std_input_handle))
	if hIn == invalid_handle_value || hIn == 0 {
		return err
	}
	ok, _, err := procSetConsoleMode.Call(hIn, uintptr(mode))
	if ok != 0 {
		err = nil
	}
	return err
}

// TerminalMode returns the current terminal input mode as an InputModeSetter.
//
// This function is provided for convenience, and should
// not be necessary for most users of liner.
func TerminalMode() (ModeApplier, error) {
	var mode inputMode
	hIn, _, err := procGetStdHandle.Call(uintptr(std_input_handle))
	if hIn == invalid_handle_value || hIn == 0 {
		return nil, err
	}
	ok, _, err := procGetConsoleMode.Call(hIn, uintptr(unsafe.Pointer(&mode)))
	if ok != 0 {
		err = nil
	}
	return mode, err
}
