package door

// Don't use :  #cgo CFLAGS: -Wall
// https://github.com/golang/go/issues/6883#issuecomment-383800123

// #cgo LDFLAGS: -lws2_32
// #include "input_windows.h"
import "C"

import (
	"bufio"
	"bytes"
	"log"
	"strings"
	"syscall"
	"time"
	"unsafe"
)

var ReaderInterval = time.Duration(200) * time.Millisecond
var ReaderTimeval syscall.Timeval = syscall.Timeval{Sec: 0, Usec: 200}

// Output a nice string representation of the rune buffer.
func extended_output(buffer []rune) string {
	var output string = string(buffer)
	output = strings.Replace(output, "\x1b", "^[", -1)
	return output
}

func RuneToInt8(r rune) int8 {
	return int8(r)
}

func Reader(d *Door) {
	// handle syscall.Handle, readerChannel *chan byte
	C.init_wsa()

	var runebuffer bytes.Buffer
	var runeread = bufio.NewReaderSize(&runebuffer, 1)

	// readerBuffer = make([]rune, 0, READ_SIZE*2)
	readerbuffer := C.malloc(C.sizeof_char * READ_SIZE)
	defer C.free(unsafe.Pointer(readerbuffer))

	defer func() {
		log.Printf("~Reader")
		if d.ReaderCanClose {
			d.wg.Done()
		}
	}()

	defer func() {
		if err := recover(); err != nil {
			log.Printf("Reader: %#v\n", err)
		}
	}()

	var r int

	for {
		read := C.windows_read(C.int(d.Config.Comm_handle), (*C.char)(readerbuffer), C.int(READ_SIZE))
		r = int(read)
		// log.Printf("windows_read: %d\n", r)

		if r == -1 {
			log.Println("window_read -1 (closed)")
			d.readerMutex.Lock()
			defer d.readerMutex.Unlock()
			if !d.ReaderClosed {
				d.ReaderClosed = true
				d.Disconnected = true
				close(d.readerChannel)
			}
			return
		}

		if r == 0 {
			// timeout
			ReadRune(d, runeread, true)
			// process(d, false)
			continue
		}
		gobytes := C.GoBytes(unsafe.Pointer(readerbuffer), read)

		if DEBUG_INPUT {
			log.Printf("Reader << %d, %#v\n", r, gobytes)
		}

		runebuffer.Write(gobytes)

		ReadRune(d, runeread, false)

		/*
			var input rune

			// Is this unicode?

			var err error = nil
			for err == nil {
				//RuneRead:

				input, _, err = runeread.ReadRune()

				if err == io.EOF {
					break // continue
				}
				if err != nil {
					if DEBUG_INPUT {
						log.Printf("ReadRune: %#v\n", err)
					}
					// errors EOF
					break // continue // break for loop
				}
				if input == unicode.ReplacementChar {
					runeread.UnreadRune()
					b, _ := runeread.ReadByte()
					if DEBUG_INPUT {
						log.Printf("Reader (byte) >> %x\n", b)
					}
					readerBuffer = append(readerBuffer, rune(b))
					// d.readerChannel <- rune(b)
				} else {
					if DEBUG_INPUT {
						log.Printf("Reader >> %x\n", input)
					}
					readerBuffer = append(readerBuffer, input)
					// d.readerChannel <- input
				}
				// process(d, true)

			} // goto RuneRead

			process(d, true)
		*/

	}
}