// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The websocket package implements Web Socket protocol server.
package websocket

// References:
//   The Web Socket protocol: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol

// TODO(ukai):
//   better logging.

import (
	"bufio"
	"io"
	"net"
	"os"
)

type WebSocketAddr string

func (addr WebSocketAddr) Network() string { return "websocket" }

func (addr WebSocketAddr) String() string { return string(addr) }

// Conn is an channels to communicate over Web Socket.
type Conn struct {
	// An origin URI of the Web Socket.
	Origin string
	// A location URI of the Web Socket.
	Location string
	// A subprotocol of the Web Socket.
	Protocol string

	buf *bufio.ReadWriter
	rwc io.ReadWriteCloser
}

// newConn creates a new Web Socket.
func newConn(origin, location, protocol string, buf *bufio.ReadWriter, rwc io.ReadWriteCloser) *Conn {
	if buf == nil {
		br := bufio.NewReader(rwc)
		bw := bufio.NewWriter(rwc)
		buf = bufio.NewReadWriter(br, bw)
	}
	ws := &Conn{origin, location, protocol, buf, rwc}
	return ws
}

func (ws *Conn) Read(msg []byte) (n int, err os.Error) {
	for {
		frameByte, err := ws.buf.ReadByte()
		if err != nil {
			return n, err
		}
		if (frameByte & 0x80) == 0x80 {
			length := 0
			for {
				c, err := ws.buf.ReadByte()
				if err != nil {
					return n, err
				}
				if (c & 0x80) == 0x80 {
					length = length*128 + int(c&0x7f)
				} else {
					break
				}
			}
			for length > 0 {
				_, err := ws.buf.ReadByte()
				if err != nil {
					return n, err
				}
				length--
			}
		} else {
			for {
				c, err := ws.buf.ReadByte()
				if err != nil {
					return n, err
				}
				if c == '\xff' {
					return n, err
				}
				if frameByte == 0 {
					if n+1 <= cap(msg) {
						msg = msg[0 : n+1]
					}
					msg[n] = c
					n++
				}
				if n >= cap(msg) {
					return n, os.E2BIG
				}
			}
		}
	}

	panic("unreachable")
}

func (ws *Conn) Write(msg []byte) (n int, err os.Error) {
	ws.buf.WriteByte(0)
	ws.buf.Write(msg)
	ws.buf.WriteByte(0xff)
	err = ws.buf.Flush()
	return len(msg), err
}

func (ws *Conn) Close() os.Error { return ws.rwc.Close() }

func (ws *Conn) LocalAddr() net.Addr { return WebSocketAddr(ws.Origin) }

func (ws *Conn) RemoteAddr() net.Addr { return WebSocketAddr(ws.Location) }

func (ws *Conn) SetTimeout(nsec int64) os.Error {
	if conn, ok := ws.rwc.(net.Conn); ok {
		return conn.SetTimeout(nsec)
	}
	return os.EINVAL
}

func (ws *Conn) SetReadTimeout(nsec int64) os.Error {
	if conn, ok := ws.rwc.(net.Conn); ok {
		return conn.SetReadTimeout(nsec)
	}
	return os.EINVAL
}

func (ws *Conn) SetWriteTimeout(nsec int64) os.Error {
	if conn, ok := ws.rwc.(net.Conn); ok {
		return conn.SetWriteTimeout(nsec)
	}
	return os.EINVAL
}

var _ net.Conn = (*Conn)(nil) // compile-time check that *Conn implements net.Conn.
