#!/bin/bash

request_init() {
	cat > request.go <<EOF
package protocol

// DO NOT EDIT
//
// This file was generated by ./schema.sh

EOF
}

response_init() {
	cat > response.go <<EOF
package protocol

// DO NOT EDIT
//
// This file was generated by ./schema.sh

import "fmt"

EOF
}

entity=$1
shift

cmd=$1
shift

schema="0"
schema_distinguisher=""

if [ "$entity" = "--request" ]; then
	if [ "$cmd" = "init" ]; then
		request_init
		exit
	fi

	cmd_only=$(echo "$cmd" | cut -f 1 -d :)
	if [ "$cmd_only" != "$cmd" ]; then
		schema=$(echo "$cmd" | cut -f 2 -d :)
		cmd="$cmd_only"
		schema_distinguisher="V$schema"
	fi

	args=""

	for i in "${@}"
	do
		name=$(echo "$i" | cut -f 1 -d :)
		type=$(echo "$i" | cut -f 2 -d :)

		if [ "$name" = "unused" ]; then
			continue
		fi

		args=$(echo "${args}, ${name} ${type}")
	done

	cat >> request.go <<EOF

// Encode${cmd}${schema_distinguisher} encodes a $cmd request.
func Encode${cmd}${schema_distinguisher}(request *Message${args}) {
	request.reset()
EOF

	for i in "${@}"
	do
		name=$(echo "$i" | cut -f 1 -d :)
		type=$(echo "$i" | cut -f 2 -d :)

		if [ "$name" = "unused" ]; then
			name=$(echo "0")
		fi

		cat >> request.go <<EOF
	request.put${type^}(${name})
EOF
	done

	cat >> request.go <<EOF

	request.putHeader(Request${cmd}, ${schema})
}
EOF

fi

if [ "$entity" = "--response" ]; then
	if [ "$cmd" = "init" ]; then
		response_init
		exit
	fi

	returns=""

	for i in "${@}"
	do
		name=$(echo "$i" | cut -f 1 -d :)
		type=$(echo "$i" | cut -f 2 -d :)

		if [ "$name" = "unused" ]; then
			continue
		fi

		returns=$(echo "${returns}${name} ${type}, ")
	done

	cat >> response.go <<EOF

// Decode${cmd} decodes a $cmd response.
func Decode${cmd}(response *Message) (${returns}err error) {
	mtype, _ := response.getHeader()

	if mtype == ResponseFailure {
		e := ErrRequest{}
		e.Code = response.getUint64()
		e.Description = response.getString()
		err = e
		return
	}

	if mtype != Response${cmd} {
		err = fmt.Errorf("decode %s: unexpected type %d", responseDesc(Response${cmd}), mtype)
		return
	}

EOF

	for i in "${@}"
	do
		name=$(echo "$i" | cut -f 1 -d :)
		type=$(echo "$i" | cut -f 2 -d :)

		assign=$(echo "${name} = ")

		if [ "$name" = "unused" ]; then
			assign=$(echo "")
		fi

		cat >> response.go <<EOF
	${assign}response.get${type^}()
EOF
	done

	cat >> response.go <<EOF

	return
}
EOF

fi
