package pgproto3

import (
	

	
)

type FunctionCall struct {
	Function         uint32
	ArgFormatCodes   []uint16
	Arguments        [][]byte
	ResultFormatCode uint16
}

// Frontend identifies this message as sendable by a PostgreSQL frontend.
func (*FunctionCall) () {}

// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
// type identifier and 4 byte message length.
func ( *FunctionCall) ( []byte) error {
	* = FunctionCall{}
	 := 0
	// Specifies the object ID of the function to call.
	.Function = binary.BigEndian.Uint32([:])
	 += 4
	// The number of argument format codes that follow (denoted C below).
	// This can be zero to indicate that there are no arguments or that the arguments all use the default format (text);
	// or one, in which case the specified format code is applied to all arguments;
	// or it can equal the actual number of arguments.
	 := int(binary.BigEndian.Uint16([:]))
	 += 2
	 := make([]uint16, )
	for  := 0;  < ; ++ {
		// The argument format codes. Each must presently be zero (text) or one (binary).
		 := binary.BigEndian.Uint16([:])
		if  != 0 &&  != 1 {
			return &invalidMessageFormatErr{messageType: "FunctionCall"}
		}
		[] = 
		 += 2
	}
	.ArgFormatCodes = 

	// Specifies the number of arguments being supplied to the function.
	 := int(binary.BigEndian.Uint16([:]))
	 += 2
	 := make([][]byte, )
	for  := 0;  < ; ++ {
		// The length of the argument value, in bytes (this count does not include itself). Can be zero.
		// As a special case, -1 indicates a NULL argument value. No value bytes follow in the NULL case.
		 := int(binary.BigEndian.Uint32([:]))
		 += 4
		if  == -1 {
			[] = nil
		} else {
			// The value of the argument, in the format indicated by the associated format code. n is the above length.
			 := [ : +]
			 += 
			[] = 
		}
	}
	.Arguments = 
	// The format code for the function result. Must presently be zero (text) or one (binary).
	 := binary.BigEndian.Uint16([:])
	if  != 0 &&  != 1 {
		return &invalidMessageFormatErr{messageType: "FunctionCall"}
	}
	.ResultFormatCode = 
	return nil
}

// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
func ( *FunctionCall) ( []byte) []byte {
	 = append(, 'F')
	 := len()
	 = pgio.AppendUint32(, 0) // Unknown length, set it at the end
	 = pgio.AppendUint32(, .Function)
	 = pgio.AppendUint16(, uint16(len(.ArgFormatCodes)))
	for ,  := range .ArgFormatCodes {
		 = pgio.AppendUint16(, )
	}
	 = pgio.AppendUint16(, uint16(len(.Arguments)))
	for ,  := range .Arguments {
		if  == nil {
			 = pgio.AppendInt32(, -1)
		} else {
			 = pgio.AppendInt32(, int32(len()))
			 = append(, ...)
		}
	}
	 = pgio.AppendUint16(, .ResultFormatCode)
	pgio.SetInt32([:], int32(len([:])))
	return 
}