// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package text

import (
	"bytes"
	"strings"

	"google.golang.org/proto/internal/errors"
)

// Marshal serializes v as the proto text format, where v must be a Message.
// In the proto text format, the top-level value is always a message where the
// delimiters are elided.
//
// If indent is a non-empty string, it causes every entry in a List or Message
// to be preceded by the indent and trailed by a newline.
//
// If delims is not the zero value, it controls the delimiter characters used
// for messages (e.g., "{}" vs "<>").
//
// If outputASCII is true, strings will be serialized in such a way that
// multi-byte UTF-8 sequences are escaped. This property ensures that the
// overall output is ASCII (as opposed to UTF-8).
func Marshal(v Value, indent string, delims [2]byte, outputASCII bool) ([]byte, error) {
	p := encoder{}
	if len(indent) > 0 {
		if strings.Trim(indent, " \t") != "" {
			return nil, errors.New("indent may only be composed of space and tab characters")
		}
		p.indent = indent
		p.newline = "\n"
	}
	switch delims {
	case [2]byte{0, 0}:
		p.delims = [2]byte{'{', '}'}
	case [2]byte{'{', '}'}, [2]byte{'<', '>'}:
		p.delims = delims
	default:
		return nil, errors.New("delimiters may only be \"{}\" or \"<>\"")
	}
	p.outputASCII = outputASCII

	err := p.marshalMessage(v, false)
	if !p.nerr.Merge(err) {
		return nil, err
	}
	if len(indent) > 0 {
		return append(bytes.TrimRight(p.out, "\n"), '\n'), p.nerr.E
	}
	return p.out, p.nerr.E
}

type encoder struct {
	nerr errors.NonFatal
	out  []byte

	indent      string
	indents     []byte
	newline     string // set to "\n" if len(indent) > 0
	delims      [2]byte
	outputASCII bool
}

func (p *encoder) marshalList(v Value) error {
	if v.Type() != List {
		return errors.New("invalid type %v, expected list", v.Type())
	}
	elems := v.List()
	p.out = append(p.out, '[')
	p.indents = append(p.indents, p.indent...)
	if len(elems) > 0 {
		p.out = append(p.out, p.newline...)
	}
	for i, elem := range elems {
		p.out = append(p.out, p.indents...)
		if err := p.marshalValue(elem); !p.nerr.Merge(err) {
			return err
		}
		if i < len(elems)-1 {
			p.out = append(p.out, ',')
		}
		p.out = append(p.out, p.newline...)
	}
	p.indents = p.indents[:len(p.indents)-len(p.indent)]
	if len(elems) > 0 {
		p.out = append(p.out, p.indents...)
	}
	p.out = append(p.out, ']')
	return nil
}

func (p *encoder) marshalMessage(v Value, emitDelims bool) error {
	if v.Type() != Message {
		return errors.New("invalid type %v, expected message", v.Type())
	}
	items := v.Message()
	if emitDelims {
		p.out = append(p.out, p.delims[0])
		p.indents = append(p.indents, p.indent...)
		if len(items) > 0 {
			p.out = append(p.out, p.newline...)
		}
	}
	for i, item := range items {
		p.out = append(p.out, p.indents...)
		if err := p.marshalKey(item[0]); !p.nerr.Merge(err) {
			return err
		}
		p.out = append(p.out, ':')
		if len(p.indent) > 0 {
			p.out = append(p.out, ' ')
		}
		if err := p.marshalValue(item[1]); !p.nerr.Merge(err) {
			return err
		}
		if i < len(items)-1 && len(p.indent) == 0 {
			p.out = append(p.out, ' ')
		}
		p.out = append(p.out, p.newline...)
	}
	if emitDelims {
		p.indents = p.indents[:len(p.indents)-len(p.indent)]
		if len(items) > 0 {
			p.out = append(p.out, p.indents...)
		}
		p.out = append(p.out, p.delims[1])
	}
	return nil
}

func (p *encoder) marshalKey(v Value) error {
	switch v.Type() {
	case String:
		var err error
		p.out = append(p.out, '[')
		if len(urlRegexp.FindString(v.str)) == len(v.str) {
			p.out = append(p.out, v.str...)
		} else {
			err = p.marshalString(v)
		}
		p.out = append(p.out, ']')
		return err
	case Uint:
		return p.marshalNumber(v)
	case Name:
		s, _ := v.Name()
		p.out = append(p.out, s...)
		return nil
	default:
		return errors.New("invalid type %v to encode key", v.Type())
	}
}

func (p *encoder) marshalValue(v Value) error {
	switch v.Type() {
	case Bool, Int, Uint, Float:
		return p.marshalNumber(v)
	case String:
		return p.marshalString(v)
	case List:
		return p.marshalList(v)
	case Message:
		return p.marshalMessage(v, true)
	case Name:
		s, _ := v.Name()
		p.out = append(p.out, s...)
		return nil
	default:
		return errors.New("invalid type %v to encode value", v.Type())
	}
}
