package httpsfv

import (
	
	
)

// ErrInvalidListFormat is returned when the format of a list is invalid.
var ErrInvalidListFormat = errors.New("invalid list format")

// List contains items an inner lists.
//
// See https://httpwg.org/specs/rfc9651.html#list
type List []Member

// marshalSFV serializes as defined in
// https://httpwg.org/specs/rfc9651.html#ser-list.
func ( List) ( *strings.Builder) error {
	 := len()
	for  := 0;  < ; ++ {
		if  := [].marshalSFV();  != nil {
			return 
		}

		if  != -1 {
			if ,  := .WriteString(", ");  != nil {
				return 
			}
		}
	}

	return nil
}

// UnmarshalList parses a list as defined in
// https://httpwg.org/specs/rfc9651.html#parse-list.
func ( []string) (List, error) {
	 := &scanner{
		data: strings.Join(, ","),
	}

	.scanWhileSp()

	,  := parseList()
	if  != nil {
		return List{}, 
	}

	return , nil
}

// parseList parses as defined in
// https://httpwg.org/specs/rfc9651.html#parse-list.
func parseList( *scanner) (List, error) {
	var  List

	for !.eof() {
		,  := parseItemOrInnerList()
		if  != nil {
			return nil, 
		}

		 = append(, )

		.scanWhileOWS()

		if .eof() {
			return , nil
		}

		if .data[.off] != ',' {
			return nil, &UnmarshalError{.off, ErrInvalidListFormat}
		}
		.off++

		.scanWhileOWS()

		if .eof() {
			// there is a trailing comma
			return nil, &UnmarshalError{.off, ErrInvalidListFormat}
		}
	}

	return , nil
}

// parseItemOrInnerList parses as defined in
// https://httpwg.org/specs/rfc9651.html#parse-item-or-list.
func parseItemOrInnerList( *scanner) (Member, error) {
	if .eof() {
		return nil, &UnmarshalError{.off, ErrInvalidInnerListFormat}
	}

	if .data[.off] == '(' {
		return parseInnerList()
	}

	return parseItem()
}