package parser

import (
	"bytes"
	"fmt"
)

type ArrayParser struct {
	*Parser

	stickyErr error
}

func NewArrayParser(b []byte) *ArrayParser {
	var err error
	if len(b) < 2 || b[0] != '{' || b[len(b)-1] != '}' {
		err = fmt.Errorf("pg: can't parse array: %s", string(b))
	} else {
		b = b[1 : len(b)-1]
	}
	return &ArrayParser{
		Parser: New(b),

		stickyErr: err,
	}
}

func (p *ArrayParser) NextElem() ([]byte, error) {
	if p.stickyErr != nil {
		return nil, p.stickyErr
	}

	switch c := p.Peek(); c {
	case '"':
		p.Advance()
		b := p.readSubstring()
		p.Skip(',')
		return b, nil
	case '{':
		b := p.readElem()
		if b != nil {
			b = append(b, '}')
		}
		p.Skip(',')
		return b, nil
	default:
		b, _ := p.ReadSep(',')
		if bytes.Equal(b, pgNull) {
			b = nil
		}
		return b, nil
	}
}

func (p *ArrayParser) readElem() []byte {
	var b []byte
	for p.Valid() {
		c := p.Read()
		switch c {
		case '"':
			b = append(b, '"')
			for {
				bb, ok := p.ReadSep('"')
				b = append(b, bb...)
				stop := len(b) > 0 && b[len(b)-1] != '\\'
				if ok {
					b = append(b, '"')
				}
				if stop {
					break
				}
			}
		case '}':
			return b
		default:
			b = append(b, c)
		}
	}
	return b
}
