package protocol

import "io"
import "fmt"

// Map is a string-to-string map with non-unique keys. Each key can be
// associated with multiple values. This is typically used for things like HTTP
// headers.
type Map map[string] []string

// ReadMap reads a map with a 16-bit length containing strings which have a
// 16-bit size. The length of the map corresponds to how many key/value pairs
// it has, and not how long the map is.
func ReadMap (reader io.Reader) (m Map, err error) {
	length, err := ReadU16(reader)
	if err != nil { return nil, err }

	m = make(Map)
	for length > 0 {
		key, err := ReadString16(reader)
		if err != nil { return m, err }
		value, err := ReadString16(reader)
		if err != nil { return m, err }
		m.Add(key, value)
		length --
	}

	return m, err
}

func (m Map) Serialize (writer io.Writer) (err error) {
	if uint(len(m)) > MaxIntOfSize(2) {
		panic(fmt.Sprintf("len(%d) cannot fit in U16", len(m)))
	}

	length := 0
	for _, item := range m {
		length += len(item)
	}
	
	err = WriteU16(writer, uint16(length))
	if err != nil { return }
	
	for key, values := range m {
	for _, value := range values {
		err = WriteString16(writer, key)
		if err != nil { return }
		err = WriteString16(writer, value)
		if err != nil { return }
	}}

	return
}

// Add adds a value to the map under the specified key.
func (m Map) Add (key, value string) {
	m[key] = append(m[key], value)
}
