package protocol

import "io"

// MessageHTTPRequest represents an HTTP or HTTPS request. It is sent from the
// router to the service.
type MessageHTTPRequest struct {
	ID
	Address string
	Method  string
	URL     string
	Header  Map
}

func ReadMessageHTTPRequest (reader io.Reader) (message MessageHTTPRequest, err error) {
	message.ID, err = ReadID(reader)
	if err != nil { return }
	message.Address, err = ReadString8(reader)
	if err != nil { return }
	message.Method, err = ReadString8(reader)
	if err != nil { return }
	message.URL, err = ReadString16(reader)
	if err != nil { return }
	message.Header, err = ReadMap(reader)
	return
}

func (message MessageHTTPRequest) Serialize (writer io.Writer) (err error) {
	err = message.ID.Serialize(writer)
	if err != nil { return }
	err = WriteString8(writer, message.Address)
	if err != nil { return }
	err = WriteString8(writer, message.Method)
	if err != nil { return }
	err = WriteString16(writer, message.URL)
	if err != nil { return }
	return message.Header.Serialize(writer)
}

func (message MessageHTTPRequest) Send (writer io.Writer) (err error) {
	err = TypeHTTPRequest.Serialize(writer)
	if err != nil { return }
	return message.Serialize(writer)
}

// MessageHTTPResponse represents an HTTP or HTTPS response. It is sent from the
// service to the router.
type MessageHTTPResponse struct {
	ID
	Status uint16
	Header Map
}

func ReadMessageHTTPResponse (reader io.Reader) (message MessageHTTPResponse, err error) {
	message.ID, err = ReadID(reader)
	if err != nil { return }
	message.Status, err = ReadU16(reader)
	if err != nil { return }
	message.Header, err = ReadMap(reader)
	return
}

func (message MessageHTTPResponse) Serialize (writer io.Writer) (err error) {
	err = message.ID.Serialize(writer)
	if err != nil { return }
	err = WriteU16(writer, message.Status)
	if err != nil { return }
	return message.Header.Serialize(writer)
}

func (message MessageHTTPResponse) Send (writer io.Writer) (err error) {
	err = TypeHTTPResponse.Serialize(writer)
	if err != nil { return }
	return message.Serialize(writer)
}

// MessageHTTPBodyRequest is sent by the service to the router to ask it to
// begin transmitting the request body as a series of MessageHTTPBodySegment.
// The router will not give the service the request body unless the service
// sends it this message.
type MessageHTTPBodyRequest struct {
	ID
}

func ReadMessageHTTPBodyRequest (reader io.Reader) (message MessageHTTPBodyRequest, err error) {
	message.ID, err = ReadID(reader)
	return
}

func (message MessageHTTPBodyRequest) Serialize (writer io.Writer) error {
	return message.ID.Serialize(writer)
}

func (message MessageHTTPBodyRequest) Send (writer io.Writer) (err error) {
	err = TypeHTTPBodyRequest.Serialize(writer)
	if err != nil { return }
	return message.Serialize(writer)
}

// MessageHTTPBodySegment is sent by both the router and the service. When the
// router sends this message, it is a segment of the request body. When the
// service sends this message, it is a segment of the response body.
type MessageHTTPBodySegment struct {
	ID
	Data []byte
}

func ReadMessageHTTPBodySegment (reader io.Reader) (message MessageHTTPBodySegment, err error) {
	message.ID, err = ReadID(reader)
	if err != nil { return }
	message.Data, err = ReadBuf16(reader)
	return
}

func (message MessageHTTPBodySegment) Serialize (writer io.Writer) (err error) {
	err = message.ID.Serialize(writer)
	if err != nil { return }
	return WriteBuf16(writer, message.Data)
}

func (message MessageHTTPBodySegment) Send (writer io.Writer) (err error) {
	err = TypeHTTPBodySegment.Serialize(writer)
	if err != nil { return }
	return message.Serialize(writer)
}

// MessageHTTPBodySegment is sent by both the router and the service. When the
// router sends this message, it means that the HTTP request body has been sent
// in its entirety. The router will not send this message unless the service has
// sent a MessageHTTPBodyRequest first. When the service sends this message, it
// means that the HTTP resposne body has been sent in its entirety. The service
// must always sends this message when it fulfills a request, as it properly
// terminates the sequence.
type MessageHTTPBodyEnd struct {
	ID
}

func ReadMessageHTTPBodyEnd (reader io.Reader) (message MessageHTTPBodyEnd, err error) {
	message.ID, err = ReadID(reader)
	return
}

func (message MessageHTTPBodyEnd) Serialize (writer io.Writer) error {
	return message.ID.Serialize(writer)
}

func (message MessageHTTPBodyEnd) Send (writer io.Writer) (err error) {
	err = TypeHTTPBodyEnd.Serialize(writer)
	if err != nil { return }
	return message.Serialize(writer)
}
