package logstorage

import (
	"strings"
	"sync"
)

type logfmtParser struct {
	fields []Field
}

func (p *logfmtParser) reset() {
	clear(p.fields)
	p.fields = p.fields[:0]
}

func (p *logfmtParser) addField(name, value string) {
	name = strings.TrimSpace(name)
	if name == "" && value == "" {
		return
	}
	p.fields = append(p.fields, Field{
		Name:  name,
		Value: value,
	})
}

func (p *logfmtParser) parse(s string) {
	p.reset()
	for {
		// Search for field name
		n := strings.IndexAny(s, "= ")
		if n < 0 {
			// empty value
			p.addField(s, "")
			return
		}

		name := s[:n]
		ch := s[n]
		s = s[n+1:]
		if ch == ' ' {
			// empty value
			p.addField(name, "")
			continue
		}
		if len(s) == 0 {
			p.addField(name, "")
			return
		}

		// Search for field value
		value, nOffset := tryUnquoteString(s, "")
		if nOffset >= 0 {
			p.addField(name, value)
			s = s[nOffset:]
			if len(s) == 0 {
				return
			}
			if s[0] != ' ' {
				return
			}
			s = s[1:]
		} else {
			n := strings.IndexByte(s, ' ')
			if n < 0 {
				p.addField(name, s)
				return
			}
			p.addField(name, s[:n])
			s = s[n+1:]
		}
	}
}

func getLogfmtParser() *logfmtParser {
	v := logfmtParserPool.Get()
	if v == nil {
		return &logfmtParser{}
	}
	return v.(*logfmtParser)
}

func putLogfmtParser(p *logfmtParser) {
	p.reset()
	logfmtParserPool.Put(p)
}

var logfmtParserPool sync.Pool