package door

import (
	"log"
	"strings"
	"syscall"
)

// https://go101.org/article/channel-closing.html

func Writer(d *Door) {
	var handle int = d.Config.Comm_handle
	log.Println("Writer")
	defer d.wg.Done()
	for {
		/*
			select {
			case <-d.closeChannel:
				if !d.WriterClosed {
					d.WriterClosed = true
					close(d.writerChannel)
				}
				log.Println("~Writer")
				return
			default:
			}
		*/

		select {
		/*
			case <-d.closeChannel:
				// Not safe from data races -- not synced
				if !d.WriterClosed {
					d.WriterClosed = true
					close(d.writerChannel)
				}
				// close(d.writerChannel)
				log.Println("~Writer")
				return
		*/
		case output, ok := <-d.writerChannel:
			if !ok {
				log.Println("closeChannel")
				// Safe from data races, writerChannel unbuffered
				d.WriterClosed = true
				close(d.writerChannel)
				/*
					if !d.Disconnect() {
						// d.Disconnected = true
						// atomic.StoreInt32(&d.Disconnected, 1)
						// if !ok, the channel is already closed...
						// close(d.writerChannel)
					}
				*/
				log.Println("~Writer")
				return

				//				d.closeChannel <- true
				//				continue
			} else {
				// log.Println("output")
				/* Handle cases where we're updating a portion of the screen.
				When we SavePos, also save/restore the last color set.
				*/
				if output == "" {
					// Close Channel
					/*
						if !d.WriterClosed {
							d.WriterClosed = true
							close(d.writerChannel)
						}
					*/
					d.SafeWriterClose()
					log.Println("~Writer")
					return

				}
				if strings.HasSuffix(output, RestorePos) {
					output += Color(d.LastColor...)

				} else {
					d.UpdateLastColor(output, &d.LastColor)
				}
				// log.Println("write output")
				buffer := []byte(output)
				n, err := syscall.Write(handle, buffer)
				if (err != nil) || (n != len(buffer)) {
					log.Println("closeChannel")
					d.SafeWriterClose()
					/*
						d.WriterClosed = true
						close(d.writerChannel)
					*/
					/*
						if !d.Disconnect() {
							// d.Disconnected = true
							// atomic.StoreInt32(&d.Disconnected, 1)
							close(d.writerChannel)
						}
					*/
					log.Println("~Writer")
					return
				}
			}
		}
	}
}

/*
func Writer(handle int, writerChannel *chan string) {
	for output := range *writerChannel {
		buffer := []byte(output)
		n, err := syscall.Write(handle, buffer)
		if (err != nil) || (n != len(buffer)) {
			close(*writerChannel)
			break
		}
	}
}
*/