// 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.

// SRPC constants, data structures, and parsing.

package srpc

import (
	"math"
	"os"
	"strconv"
	"syscall"
	"unsafe"
)

// An Errno is an SRPC status code.
type Errno uint32

const (
	OK Errno = 256 + iota
	ErrBreak
	ErrMessageTruncated
	ErrNoMemory
	ErrProtocolMismatch
	ErrBadRPCNumber
	ErrBadArgType
	ErrTooFewArgs
	ErrTooManyArgs
	ErrInArgTypeMismatch
	ErrOutArgTypeMismatch
	ErrInternalError
	ErrAppError
)

var errstr = [...]string{
	OK - OK:                    "ok",
	ErrBreak - OK:              "break",
	ErrMessageTruncated - OK:   "message truncated",
	ErrNoMemory - OK:           "out of memory",
	ErrProtocolMismatch - OK:   "protocol mismatch",
	ErrBadRPCNumber - OK:       "invalid RPC method number",
	ErrBadArgType - OK:         "unexpected argument type",
	ErrTooFewArgs - OK:         "too few arguments",
	ErrTooManyArgs - OK:        "too many arguments",
	ErrInArgTypeMismatch - OK:  "input argument type mismatch",
	ErrOutArgTypeMismatch - OK: "output argument type mismatch",
	ErrInternalError - OK:      "internal error",
	ErrAppError - OK:           "application error",
}

func (e Errno) String() string {
	if e < OK || int(e-OK) >= len(errstr) {
		return "Errno(" + strconv.Itoa64(int64(e)) + ")"
	}
	return errstr[e-OK]
}

// A *msgHdr is the data argument to the imc_recvmsg
// and imc_sendmsg system calls.  Because it contains unchecked
// counts trusted by the system calls, the data structure is unsafe
// to expose to package clients.
type msgHdr struct {
	iov   *iov
	niov  int32
	desc  *int32
	ndesc int32
	flags uint32
}

// A single region for I/O.  Just as unsafe as msgHdr.
type iov struct {
	base *byte
	len  int32
}

// A msg is the Go representation of a message.
type msg struct {
	rdata []byte  // data being consumed during message parsing
	rdesc []int32 // file descriptors being consumed during message parsing
	wdata []byte  // data being generated when replying

	// parsed version of message
	protocol  uint32
	requestId uint64
	isReq     bool
	rpcNumber uint32
	gotHeader bool
	status    Errno         // error code sent in response
	Arg       []interface{} // method arguments
	Ret       []interface{} // method results
	Size      []int         // max sizes for arrays in method results
	fmt       string        // accumulated format string of arg+":"+ret
}

// A msgReceiver receives messages from a file descriptor.
type msgReceiver struct {
	fd   int
	data [128 * 1024]byte
	desc [8]int32
	hdr  msgHdr
	iov  iov
}

func (r *msgReceiver) recv() (*msg, os.Error) {
	// Init pointers to buffers where syscall recvmsg can write.
	r.iov.base = &r.data[0]
	r.iov.len = int32(len(r.data))
	r.hdr.iov = &r.iov
	r.hdr.niov = 1
	r.hdr.desc = &r.desc[0]
	r.hdr.ndesc = int32(len(r.desc))
	n, _, e := syscall.Syscall(syscall.SYS_IMC_RECVMSG, uintptr(r.fd), uintptr(unsafe.Pointer(&r.hdr)), 0)
	if e != 0 {
		return nil, os.NewSyscallError("imc_recvmsg", int(e))
	}

	// Make a copy of the data so that the next recvmsg doesn't
	// smash it.  The system call did not update r.iov.len.  Instead it
	// returned the total byte count as n.
	m := new(msg)
	m.rdata = make([]byte, n)
	copy(m.rdata, &r.data)

	// Make a copy of the desc too.
	// The system call *did* update r.hdr.ndesc.
	if r.hdr.ndesc > 0 {
		m.rdesc = make([]int32, r.hdr.ndesc)
		for i := range m.rdesc {
			m.rdesc[i] = r.desc[i]
		}
	}

	return m, nil
}

// A msgSender sends messages on a file descriptor.
type msgSender struct {
	fd  int
	hdr msgHdr
	iov iov
}

func (s *msgSender) send(m *msg) os.Error {
	if len(m.wdata) > 0 {
		s.iov.base = &m.wdata[0]
	}
	s.iov.len = int32(len(m.wdata))
	s.hdr.iov = &s.iov
	s.hdr.niov = 1
	s.hdr.desc = nil
	s.hdr.ndesc = 0
	_, _, e := syscall.Syscall(syscall.SYS_IMC_SENDMSG, uintptr(s.fd), uintptr(unsafe.Pointer(&s.hdr)), 0)
	if e != 0 {
		return os.NewSyscallError("imc_sendmsg", int(e))
	}
	return nil
}

// Reading from msg.rdata.
func (m *msg) uint8() uint8 {
	if m.status != OK {
		return 0
	}
	if len(m.rdata) < 1 {
		m.status = ErrMessageTruncated
		return 0
	}
	x := m.rdata[0]
	m.rdata = m.rdata[1:]
	return x
}

func (m *msg) uint32() uint32 {
	if m.status != OK {
		return 0
	}
	if len(m.rdata) < 4 {
		m.status = ErrMessageTruncated
		return 0
	}
	b := m.rdata[0:4]
	x := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
	m.rdata = m.rdata[4:]
	return x
}

func (m *msg) uint64() uint64 {
	if m.status != OK {
		return 0
	}
	if len(m.rdata) < 8 {
		m.status = ErrMessageTruncated
		return 0
	}
	b := m.rdata[0:8]
	x := uint64(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
	x |= uint64(uint32(b[4])|uint32(b[5])<<8|uint32(b[6])<<16|uint32(b[7])<<24) << 32
	m.rdata = m.rdata[8:]
	return x
}

func (m *msg) bytes(n int) []byte {
	if m.status != OK {
		return nil
	}
	if len(m.rdata) < n {
		m.status = ErrMessageTruncated
		return nil
	}
	x := m.rdata[0:n]
	m.rdata = m.rdata[n:]
	return x
}

// Writing to msg.wdata.
func (m *msg) grow(n int) []byte {
	i := len(m.wdata)
	if i+n > cap(m.wdata) {
		a := make([]byte, i, (i+n)*2)
		copy(a, m.wdata)
		m.wdata = a
	}
	m.wdata = m.wdata[0 : i+n]
	return m.wdata[i : i+n]
}

func (m *msg) wuint8(x uint8) { m.grow(1)[0] = x }

func (m *msg) wuint32(x uint32) {
	b := m.grow(4)
	b[0] = byte(x)
	b[1] = byte(x >> 8)
	b[2] = byte(x >> 16)
	b[3] = byte(x >> 24)
}

func (m *msg) wuint64(x uint64) {
	b := m.grow(8)
	lo := uint32(x)
	b[0] = byte(lo)
	b[1] = byte(lo >> 8)
	b[2] = byte(lo >> 16)
	b[3] = byte(lo >> 24)
	hi := uint32(x >> 32)
	b[4] = byte(hi)
	b[5] = byte(hi >> 8)
	b[6] = byte(hi >> 16)
	b[7] = byte(hi >> 24)
}

func (m *msg) wbytes(p []byte) { copy(m.grow(len(p)), p) }

func (m *msg) wstring(s string) {
	b := m.grow(len(s))
	for i := range b {
		b[i] = s[i]
	}
}

// Parsing of RPC header and arguments.
//
// The header format is:
//	protocol uint32;
//	requestId uint64;
//	isReq bool;
//	rpcNumber uint32;
//	status uint32;  // only for response
//
// Then a sequence of values follow, preceded by the length:
//	nvalue uint32;
//
// Each value begins with a one-byte type followed by
// type-specific data.
//
//	type uint8;
//	'b':	x bool;
//	'C':	len uint32; x [len]byte;
//	'd':	x float64;
//	'D':	len uint32; x [len]float64;
//	'h':	x int;	// handle aka file descriptor
//	'i':	x int32;
//	'I':	len uint32; x [len]int32;
//	's':	len uint32; x [len]byte;
//
// If this is a request, a sequence of pseudo-values follows,
// preceded by its length (nvalue uint32).
//
// Each pseudo-value is a one-byte type as above,
// followed by a maximum length (len uint32)
// for the 'C', 'D', 'I', and 's' types.
//
// In the Go msg, we represent each argument by
// an empty interface containing the type of x in the
// corresponding case.

// The current protocol number.
const protocol = 0xc0da0002

func (m *msg) unpackHeader() {
	m.protocol = m.uint32()
	m.requestId = m.uint64()
	m.isReq = m.uint8() != 0
	m.rpcNumber = m.uint32()
	m.gotHeader = m.status == OK // signal that header parsed successfully
	if m.gotHeader && !m.isReq {
		status := Errno(m.uint32())
		m.gotHeader = m.status == OK // still ok?
		if m.gotHeader {
			m.status = status
		}
	}
}

func (m *msg) packHeader() {
	m.wuint32(m.protocol)
	m.wuint64(m.requestId)
	if m.isReq {
		m.wuint8(1)
	} else {
		m.wuint8(0)
	}
	m.wuint32(m.rpcNumber)
	if !m.isReq {
		m.wuint32(uint32(m.status))
	}
}

func (m *msg) unpackValues(v []interface{}) {
	for i := range v {
		t := m.uint8()
		m.fmt += string(t)
		switch t {
		default:
			if m.status == OK {
				m.status = ErrBadArgType
			}
			return
		case 'b': // bool[1]
			v[i] = m.uint8() > 0
		case 'C': // char array
			v[i] = m.bytes(int(m.uint32()))
		case 'd': // double
			v[i] = math.Float64frombits(m.uint64())
		case 'D': // double array
			a := make([]float64, int(m.uint32()))
			for j := range a {
				a[j] = math.Float64frombits(m.uint64())
			}
			v[i] = a
		case 'h': // file descriptor (handle)
			if len(m.rdesc) == 0 {
				if m.status == OK {
					m.status = ErrBadArgType
				}
				return
			}
			v[i] = int(m.rdesc[0])
			m.rdesc = m.rdesc[1:]
		case 'i': // int
			v[i] = int32(m.uint32())
		case 'I': // int array
			a := make([]int32, int(m.uint32()))
			for j := range a {
				a[j] = int32(m.uint32())
			}
			v[i] = a
		case 's': // string
			v[i] = string(m.bytes(int(m.uint32())))
		}
	}
}

func (m *msg) packValues(v []interface{}) {
	for i := range v {
		switch x := v[i].(type) {
		default:
			if m.status == OK {
				m.status = ErrInternalError
			}
			return
		case bool:
			m.wuint8('b')
			if x {
				m.wuint8(1)
			} else {
				m.wuint8(0)
			}
		case []byte:
			m.wuint8('C')
			m.wuint32(uint32(len(x)))
			m.wbytes(x)
		case float64:
			m.wuint8('d')
			m.wuint64(math.Float64bits(x))
		case []float64:
			m.wuint8('D')
			m.wuint32(uint32(len(x)))
			for _, f := range x {
				m.wuint64(math.Float64bits(f))
			}
		case int32:
			m.wuint8('i')
			m.wuint32(uint32(x))
		case []int32:
			m.wuint8('I')
			m.wuint32(uint32(len(x)))
			for _, i := range x {
				m.wuint32(uint32(i))
			}
		case string:
			m.wuint8('s')
			m.wuint32(uint32(len(x)))
			m.wstring(x)
		}
	}
}

func (m *msg) unpackRequest() {
	m.status = OK
	if m.unpackHeader(); m.status != OK {
		return
	}
	if m.protocol != protocol || !m.isReq {
		m.status = ErrProtocolMismatch
		return
	}

	// type-tagged argument values
	m.Arg = make([]interface{}, m.uint32())
	m.unpackValues(m.Arg)
	if m.status != OK {
		return
	}

	// type-tagged expected return sizes.
	// fill in zero values for each return value
	// and save sizes.
	m.fmt += ":"
	m.Ret = make([]interface{}, m.uint32())
	m.Size = make([]int, len(m.Ret))
	for i := range m.Ret {
		t := m.uint8()
		m.fmt += string(t)
		switch t {
		default:
			if m.status == OK {
				m.status = ErrBadArgType
			}
			return
		case 'b': // bool[1]
			m.Ret[i] = false
		case 'C': // char array
			m.Size[i] = int(m.uint32())
			m.Ret[i] = []byte(nil)
		case 'd': // double
			m.Ret[i] = float64(0)
		case 'D': // double array
			m.Size[i] = int(m.uint32())
			m.Ret[i] = []float64(nil)
		case 'h': // file descriptor (handle)
			m.Ret[i] = int(-1)
		case 'i': // int
			m.Ret[i] = int32(0)
		case 'I': // int array
			m.Size[i] = int(m.uint32())
			m.Ret[i] = []int32(nil)
		case 's': // string
			m.Size[i] = int(m.uint32())
			m.Ret[i] = ""
		}
	}
}

func (m *msg) packRequest() {
	m.packHeader()
	m.wuint32(uint32(len(m.Arg)))
	m.packValues(m.Arg)
	m.wuint32(uint32(len(m.Ret)))
	for i, v := range m.Ret {
		switch x := v.(type) {
		case bool:
			m.wuint8('b')
		case []byte:
			m.wuint8('C')
			m.wuint32(uint32(m.Size[i]))
		case float64:
			m.wuint8('d')
		case []float64:
			m.wuint8('D')
			m.wuint32(uint32(m.Size[i]))
		case int:
			m.wuint8('h')
		case int32:
			m.wuint8('i')
		case []int32:
			m.wuint8('I')
			m.wuint32(uint32(m.Size[i]))
		case string:
			m.wuint8('s')
			m.wuint32(uint32(m.Size[i]))
		}
	}
}

func (m *msg) unpackResponse() {
	m.status = OK
	if m.unpackHeader(); m.status != OK {
		return
	}
	if m.protocol != protocol || m.isReq {
		m.status = ErrProtocolMismatch
		return
	}

	// type-tagged return values
	m.fmt = ""
	m.Ret = make([]interface{}, m.uint32())
	m.unpackValues(m.Ret)
}

func (m *msg) packResponse() {
	m.packHeader()
	m.wuint32(uint32(len(m.Ret)))
	m.packValues(m.Ret)
}
