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()
	var Closed bool = false

	for output := range d.writerChannel {
		// 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 == "" {
			Closed = true
			continue
		}

		if Closed {
			log.Println("ignoring write output.")
			continue
		}

		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")
			Closed = true
			d.writerMutex.Lock()
			if !d.WriterClosed {
				d.WriterClosed = true
				// close(d.writerChannel)
			}
			d.writerMutex.Unlock()
		}
	}
	log.Println("closeChannel")

	d.writerMutex.Lock()
	if !d.WriterClosed {
		// Safe from data races, writerChannel unbuffered
		d.WriterClosed = true
	}
	d.writerMutex.Unlock()
	log.Println("~Writer")
}