package xgb

import (
	"errors"
	"io"
	"log"
	"net"
	"os"
	"sync"
)

var (
	// Where to log error-messages. Defaults to stderr.
	// To disable logging, just set this to log.New(ioutil.Discard, "", 0)
	Logger = log.New(os.Stderr, "XGB: ", log.Lshortfile)

	// ExtLock is a lock used whenever new extensions are initialized.
	// It should not be used. It is exported for use in the extension
	// sub-packages.
	ExtLock sync.Mutex
)

const (
	// cookieBuffer represents the queue size of cookies existing at any
	// point in time. The size of the buffer is really only important when
	// there are many requests without replies made in sequence. Once the
	// buffer fills, a round trip request is made to clear the buffer.
	cookieBuffer = 1000

	// xidBuffer represents the queue size of the xid channel.
	// I don't think this value matters much, since xid generation is not
	// that expensive.
	xidBuffer = 5

	// seqBuffer represents the queue size of the sequence number channel.
	// I don't think this value matters much, since sequence number generation
	// is not that expensive.
	seqBuffer = 5

	// reqBuffer represents the queue size of the number of requests that
	// can be made until new ones block. This value seems OK.
	reqBuffer = 100

	// eventBuffer represents the queue size of the number of events or errors
	// that can be loaded off the wire and not grabbed with WaitForEvent
	// until reading an event blocks. This value should be big enough to handle
	// bursts of events.
	eventBuffer = 5000
)

// A Conn represents a connection to an X server.
type Conn struct {
	host          string
	conn          net.Conn
	display       string
	DisplayNumber int
	DefaultScreen int
	SetupBytes    []byte

	setupResourceIdBase uint32
	setupResourceIdMask uint32

	eventChan  chan eventOrError
	cookieChan chan *Cookie
	xidChan    chan xid
	seqChan    chan uint16
	reqChan    chan *request
	closing    chan chan struct{}

	// Extensions is a map from extension name to major opcode. It should
	// not be used. It is exported for use in the extension sub-packages.
	Extensions map[string]byte
}

// NewConn creates a new connection instance. It initializes locks, data
// structures, and performs the initial handshake. (The code for the handshake
// has been relegated to conn.go.)
func NewConn() (*Conn, error) {
	return NewConnDisplay("")
}

// NewConnDisplay is just like NewConn, but allows a specific DISPLAY
// string to be used.
// If 'display' is empty it will be taken from os.Getenv("DISPLAY").
//
// Examples:
//	NewConn(":1") -> net.Dial("unix", "", "/tmp/.X11-unix/X1")
//	NewConn("/tmp/launch-12/:0") -> net.Dial("unix", "", "/tmp/launch-12/:0")
//	NewConn("hostname:2.1") -> net.Dial("tcp", "", "hostname:6002")
//	NewConn("tcp/hostname:1.0") -> net.Dial("tcp", "", "hostname:6001")
func NewConnDisplay(display string) (*Conn, error) {
	conn := &Conn{}

	// First connect. This reads authority, checks DISPLAY environment
	// variable, and loads the initial Setup info.
	err := conn.connect(display)
	if err != nil {
		return nil, err
	}

	return postNewConn(conn)
}

// NewConnDisplay is just like NewConn, but allows a specific net.Conn
// to be used.
func NewConnNet(netConn net.Conn) (*Conn, error) {
	conn := &Conn{}

	// First connect. This reads authority, checks DISPLAY environment
	// variable, and loads the initial Setup info.
	err := conn.connectNet(netConn)

	if err != nil {
		return nil, err
	}

	return postNewConn(conn)
}

func postNewConn(conn *Conn) (*Conn, error) {
	conn.Extensions = make(map[string]byte)

	conn.cookieChan = make(chan *Cookie, cookieBuffer)
	conn.xidChan = make(chan xid, xidBuffer)
	conn.seqChan = make(chan uint16, seqBuffer)
	conn.reqChan = make(chan *request, reqBuffer)
	conn.eventChan = make(chan eventOrError, eventBuffer)
	conn.closing = make(chan chan struct{}, 1)

	go conn.generateXIds()
	go conn.generateSeqIds()
	go conn.sendRequests()
	go conn.readResponses()

	return conn, nil
}

// Close gracefully closes the connection to the X server.
func (c *Conn) Close() {
	close(c.reqChan)
}

// Event is an interface that can contain any of the events returned by the
// server. Use a type assertion switch to extract the Event structs.
type Event interface {
	Bytes() []byte
	String() string
}

// NewEventFun is the type of function use to construct events from raw bytes.
// It should not be used. It is exported for use in the extension sub-packages.
type NewEventFun func(buf []byte) Event

// NewEventFuncs is a map from event numbers to functions that create
// the corresponding event. It should not be used. It is exported for use
// in the extension sub-packages.
var NewEventFuncs = make(map[int]NewEventFun)

// NewExtEventFuncs is a temporary map that stores event constructor functions
// for each extension. When an extension is initialized, each event for that
// extension is added to the 'NewEventFuncs' map. It should not be used. It is
// exported for use in the extension sub-packages.
var NewExtEventFuncs = make(map[string]map[int]NewEventFun)

// Error is an interface that can contain any of the errors returned by
// the server. Use a type assertion switch to extract the Error structs.
type Error interface {
	SequenceId() uint16
	BadId() uint32
	Error() string
}

// NewErrorFun is the type of function use to construct errors from raw bytes.
// It should not be used. It is exported for use in the extension sub-packages.
type NewErrorFun func(buf []byte) Error

// NewErrorFuncs is a map from error numbers to functions that create
// the corresponding error. It should not be used. It is exported for use in
// the extension sub-packages.
var NewErrorFuncs = make(map[int]NewErrorFun)

// NewExtErrorFuncs is a temporary map that stores error constructor functions
// for each extension. When an extension is initialized, each error for that
// extension is added to the 'NewErrorFuncs' map. It should not be used. It is
// exported for use in the extension sub-packages.
var NewExtErrorFuncs = make(map[string]map[int]NewErrorFun)

// eventOrError corresponds to values that can be either an event or an
// error.
type eventOrError interface{}

// NewId generates a new unused ID for use with requests like CreateWindow.
// If no new ids can be generated, the id returned is 0 and error is non-nil.
// This shouldn't be used directly, and is exported for use in the extension
// sub-packages.
// If you need identifiers, use the appropriate constructor.
// e.g., For a window id, use xproto.NewWindowId. For
// a new pixmap id, use xproto.NewPixmapId. And so on.
func (c *Conn) NewId() (uint32, error) {
	xid := <-c.xidChan
	if xid.err != nil {
		return 0, xid.err
	}
	return xid.id, nil
}

// xid encapsulates a resource identifier being sent over the Conn.xidChan
// channel. If no new resource id can be generated, id is set to 0 and a
// non-nil error is set in xid.err.
type xid struct {
	id  uint32
	err error
}

// generateXids sends new Ids down the channel for NewId to use.
// generateXids should be run in its own goroutine.
// This needs to be updated to use the XC Misc extension once we run out of
// new ids.
// Thanks to libxcb/src/xcb_xid.c. This code is greatly inspired by it.
func (conn *Conn) generateXIds() {
	defer close(conn.xidChan)

	// This requires some explanation. From the horse's mouth:
	// "The resource-id-mask contains a single contiguous set of bits (at least
	// 18).  The client allocates resource IDs for types WINDOW, PIXMAP,
	// CURSOR, FONT, GCONTEXT, and COLORMAP by choosing a value with only some
	// subset of these bits set and ORing it with resource-id-base. Only values
	// constructed in this way can be used to name newly created resources over
	// this connection."
	// So for example (using 8 bit integers), the mask might look like:
	// 00111000
	// So that valid values would be 00101000, 00110000, 00001000, and so on.
	// Thus, the idea is to increment it by the place of the last least
	// significant '1'. In this case, that value would be 00001000. To get
	// that value, we can AND the original mask with its two's complement:
	// 00111000 & 11001000 = 00001000.
	// And we use that value to increment the last resource id to get a new one.
	// (And then, of course, we OR it with resource-id-base.)
	inc := conn.setupResourceIdMask & -conn.setupResourceIdMask
	max := conn.setupResourceIdMask
	last := uint32(0)
	for {
		// TODO: Use the XC Misc extension to look for released ids.
		if last > 0 && last >= max-inc+1 {
			conn.xidChan <- xid{
				id: 0,
				err: errors.New("There are no more available resource" +
					"identifiers."),
			}
		}

		last += inc
		conn.xidChan <- xid{
			id:  last | conn.setupResourceIdBase,
			err: nil,
		}
	}
}

// newSeqId fetches the next sequence id from the Conn.seqChan channel.
func (c *Conn) newSequenceId() uint16 {
	return <-c.seqChan
}

// generateSeqIds returns new sequence ids. It is meant to be run in its
// own goroutine.
// A sequence id is generated for *every* request. It's the identifier used
// to match up replies with requests.
// Since sequence ids can only be 16 bit integers we start over at zero when it
// comes time to wrap.
// N.B. As long as the cookie buffer is less than 2^16, there are no limitations
// on the number (or kind) of requests made in sequence.
func (c *Conn) generateSeqIds() {
	defer close(c.seqChan)

	seqid := uint16(1)
	for {
		c.seqChan <- seqid
		if seqid == uint16((1<<16)-1) {
			seqid = 0
		} else {
			seqid++
		}
	}
}

// request encapsulates a buffer of raw bytes (containing the request data)
// and a cookie, which when combined represents a single request.
// The cookie is used to match up the reply/error.
type request struct {
	buf    []byte
	cookie *Cookie

	// seq is closed when the request (cookie) has been sequenced by the Conn.
	seq chan struct{}
}

// NewRequest takes the bytes and a cookie of a particular request, constructs
// a request type, and sends it over the Conn.reqChan channel.
// Note that the sequence number is added to the cookie after it is sent
// over the request channel, but before it is sent to X.
//
// Note that you may safely use NewRequest to send arbitrary byte requests
// to X. The resulting cookie can be used just like any normal cookie and
// abides by the same rules, except that for replies, you'll get back the
// raw byte data. This may be useful for performance critical sections where
// every allocation counts, since all X requests in XGB allocate a new byte
// slice. In contrast, NewRequest allocates one small request struct and
// nothing else. (Except when the cookie buffer is full and has to be flushed.)
//
// If you're using NewRequest manually, you'll need to use NewCookie to create
// a new cookie.
//
// In all likelihood, you should be able to copy and paste with some minor
// edits the generated code for the request you want to issue.
func (c *Conn) NewRequest(buf []byte, cookie *Cookie) {
	seq := make(chan struct{})
	c.reqChan <- &request{buf: buf, cookie: cookie, seq: seq}
	<-seq
}

// sendRequests is run as a single goroutine that takes requests and writes
// the bytes to the wire and adds the cookie to the cookie queue.
// It is meant to be run as its own goroutine.
func (c *Conn) sendRequests() {
	defer close(c.cookieChan)

	for req := range c.reqChan {
		// ho there! if the cookie channel is nearly full, force a round
		// trip to clear out the cookie buffer.
		// Note that we circumvent the request channel, because we're *in*
		// the request channel.
		if len(c.cookieChan) == cookieBuffer-1 {
			if err := c.noop(); err != nil {
				// Shut everything down.
				break
			}
		}
		req.cookie.Sequence = c.newSequenceId()
		close(req.seq)
		c.cookieChan <- req.cookie
		c.writeBuffer(req.buf)
	}
	response := make(chan struct{})
	c.closing <- response
	c.noop() // Flush the response reading goroutine, ignore error.
	<-response
	c.conn.Close()
}

// noop circumvents the usual request sending goroutines and forces a round
// trip request manually.
func (c *Conn) noop() error {
	cookie := c.NewCookie(true, true)
	cookie.Sequence = c.newSequenceId()
	c.cookieChan <- cookie
	if err := c.writeBuffer(c.getInputFocusRequest()); err != nil {
		return err
	}
	cookie.Reply() // wait for the buffer to clear
	return nil
}

// writeBuffer is a convenience function for writing a byte slice to the wire.
func (c *Conn) writeBuffer(buf []byte) error {
	if _, err := c.conn.Write(buf); err != nil {
		Logger.Printf("A write error is unrecoverable: %s", err)
		return err
	} else {
		return nil
	}
}

// readResponses is a goroutine that reads events, errors and
// replies off the wire.
// When an event is read, it is always added to the event channel.
// When an error is read, if it corresponds to an existing checked cookie,
// it is sent to that cookie's error channel. Otherwise it is added to the
// event channel.
// When a reply is read, it is added to the corresponding cookie's reply
// channel. (It is an error if no such cookie exists in this case.)
// Finally, cookies that came "before" this reply are always cleaned up.
func (c *Conn) readResponses() {
	defer close(c.eventChan)

	var (
		err        Error
		seq        uint16
		replyBytes []byte
	)

	for {
		select {
		case respond := <-c.closing:
			respond <- struct{}{}
			return
		default:
		}

		buf := make([]byte, 32)
		err, seq = nil, 0
		if _, err := io.ReadFull(c.conn, buf); err != nil {
			Logger.Printf("A read error is unrecoverable: %s", err)
			c.eventChan <- err
			c.Close()
			continue
		}
		switch buf[0] {
		case 0: // This is an error
			// Use the constructor function for this error (that is auto
			// generated) by looking it up by the error number.
			newErrFun, ok := NewErrorFuncs[int(buf[1])]
			if !ok {
				Logger.Printf("BUG: Could not find error constructor function "+
					"for error with number %d.", buf[1])
				continue
			}
			err = newErrFun(buf)
			seq = err.SequenceId()

			// This error is either sent to the event channel or a specific
			// cookie's error channel below.
		case 1: // This is a reply
			seq = Get16(buf[2:])

			// check to see if this reply has more bytes to be read
			size := Get32(buf[4:])
			if size > 0 {
				byteCount := 32 + size*4
				biggerBuf := make([]byte, byteCount)
				copy(biggerBuf[:32], buf)
				if _, err := io.ReadFull(c.conn, biggerBuf[32:]); err != nil {
					Logger.Printf("A read error is unrecoverable: %s", err)
					c.eventChan <- err
					c.Close()
					continue
				}
				replyBytes = biggerBuf
			} else {
				replyBytes = buf
			}

			// This reply is sent to its corresponding cookie below.
		default: // This is an event
			// Use the constructor function for this event (like for errors,
			// and is also auto generated) by looking it up by the event number.
			// Note that we AND the event number with 127 so that we ignore
			// the most significant bit (which is set when it was sent from
			// a SendEvent request).
			evNum := int(buf[0] & 127)
			newEventFun, ok := NewEventFuncs[evNum]
			if !ok {
				Logger.Printf("BUG: Could not find event construct function "+
					"for event with number %d.", evNum)
				continue
			}
			c.eventChan <- newEventFun(buf)
			continue
		}

		// At this point, we have a sequence number and we're either
		// processing an error or a reply, which are both responses to
		// requests. So all we have to do is find the cookie corresponding
		// to this error/reply, and send the appropriate data to it.
		// In doing so, we make sure that any cookies that came before it
		// are marked as successful if they are void and checked.
		// If there's a cookie that requires a reply that is before this
		// reply, then something is wrong.
		for cookie := range c.cookieChan {
			// This is the cookie we're looking for. Process and break.
			if cookie.Sequence == seq {
				if err != nil { // this is an error to a request
					// synchronous processing
					if cookie.errorChan != nil {
						cookie.errorChan <- err
					} else { // asynchronous processing
						c.eventChan <- err
						// if this is an unchecked reply, ping the cookie too
						if cookie.pingChan != nil {
							cookie.pingChan <- true
						}
					}
				} else { // this is a reply
					if cookie.replyChan == nil {
						Logger.Printf("Reply with sequence id %d does not "+
							"have a cookie with a valid reply channel.", seq)
						continue
					} else {
						cookie.replyChan <- replyBytes
					}
				}
				break
			}

			switch {
			// Checked requests with replies
			case cookie.replyChan != nil && cookie.errorChan != nil:
				Logger.Printf("Found cookie with sequence id %d that is "+
					"expecting a reply but will never get it. Currently "+
					"on sequence number %d", cookie.Sequence, seq)
			// Unchecked requests with replies
			case cookie.replyChan != nil && cookie.pingChan != nil:
				Logger.Printf("Found cookie with sequence id %d that is "+
					"expecting a reply (and not an error) but will never "+
					"get it. Currently on sequence number %d",
					cookie.Sequence, seq)
			// Checked requests without replies
			case cookie.pingChan != nil && cookie.errorChan != nil:
				cookie.pingChan <- true
				// Unchecked requests without replies don't have any channels,
				// so we can't do anything with them except let them pass by.
			}
		}
	}
}

// processEventOrError takes an eventOrError, type switches on it,
// and returns it in Go idiomatic style.
func processEventOrError(everr eventOrError) (Event, Error) {
	switch ee := everr.(type) {
	case Event:
		return ee, nil
	case Error:
		return nil, ee
	default:
		Logger.Printf("Invalid event/error type: %T", everr)
		return nil, nil
	}
}

// WaitForEvent returns the next event from the server.
// It will block until an event is available.
// WaitForEvent returns either an Event or an Error. (Returning both
// is a bug.) Note than an Error here is an X error and not an XGB error. That
// is, X errors are sometimes completely expected (and you may want to ignore
// them in some cases).
//
// If both the event and error are nil, then the connection has been closed.
func (c *Conn) WaitForEvent() (Event, Error) {
	return processEventOrError(<-c.eventChan)
}

// PollForEvent returns the next event from the server if one is available in
// the internal queue without blocking. Note that unlike WaitForEvent, both
// Event and Error could be nil. Indeed, they are both nil when the event queue
// is empty.
func (c *Conn) PollForEvent() (Event, Error) {
	select {
	case everr := <-c.eventChan:
		return processEventOrError(everr)
	default:
		return nil, nil
	}
}
