package protocol

import "io"

// MessageGeminiRequest represents a gemini request. It is sent from the router
// to the service.
type MessageGeminiRequest struct {
	ID
	Address string
	URL     string
}

func ReadMessageGeminiRequest (reader io.Reader) (message MessageGeminiRequest, err error) {
	message.ID, err = ReadID(reader)
	if err != nil { return }
	message.Address, err = ReadString8(reader)
	if err != nil { return }
	message.URL, err = ReadString16(reader)
	return
}
func (message MessageGeminiRequest) Serialize (writer io.Writer) (err error) {
	err = message.ID.Serialize(writer)
	if err != nil { return }
	err = WriteString8(writer, message.Address)
	if err != nil { return }
	return WriteString16(writer, message.URL)
}

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

// MessageGeminiResponse represents a gemini response. It is sent from the
// service to the router.
type MessageGeminiResponse struct {
	ID
	Status uint8
	Meta   string
}

func ReadMessageGeminiResponse (reader io.Reader) (message MessageGeminiResponse, err error) {
	message.ID, err = ReadID(reader)
	if err != nil { return }
	message.Status, err = ReadU8(reader)
	if err != nil { return }
	message.Meta, err = ReadString16(reader)
	return
}

func (message MessageGeminiResponse) Serialize (writer io.Writer) (err error) {
	err = message.ID.Serialize(writer)
	if err != nil { return }
	err = WriteU8(writer, message.Status)
	if err != nil { return }
	return WriteString16(writer, message.Meta)
}

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

// MessageGeminiBodySegment is a segment of a gemini response body. It is sent
// from the service to the router.
type MessageGeminiBodySegment struct {
	ID
	Data []byte
}

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

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

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

// MessageGeminiBodyEnd denotes the end of a gemini response body. It is sent
// from the service to the router. This must always be sent by the service to
// properly close the sequence, even if no response body segments were sent.
type MessageGeminiBodyEnd struct {
	ID
}

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

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

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