// 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 defval marshals and unmarshals textual forms of default values.
//
// This package handles both the form historically used in Go struct field tags
// and also the form used by google.protobuf.FieldDescriptorProto.default_value
// since they differ in superficial ways.
package defval

import (
	"fmt"
	"math"
	"strconv"

	ptext "google.golang.org/protobuf/internal/encoding/text"
	errors "google.golang.org/protobuf/internal/errors"
	pref "google.golang.org/protobuf/reflect/protoreflect"
)

// Format is the serialization format used to represent the default value.
type Format int

const (
	_ Format = iota

	// Descriptor uses the serialization format that protoc uses with the
	// google.protobuf.FieldDescriptorProto.default_value field.
	Descriptor

	// GoTag uses the historical serialization format in Go struct field tags.
	GoTag
)

// Unmarshal deserializes the default string s according to the given kind k.
// When k is an enum, a list of enum value descriptors must be provided.
func Unmarshal(s string, k pref.Kind, evs pref.EnumValueDescriptors, f Format) (pref.Value, pref.EnumValueDescriptor, error) {
	switch k {
	case pref.BoolKind:
		if f == GoTag {
			switch s {
			case "1":
				return pref.ValueOf(true), nil, nil
			case "0":
				return pref.ValueOf(false), nil, nil
			}
		} else {
			switch s {
			case "true":
				return pref.ValueOf(true), nil, nil
			case "false":
				return pref.ValueOf(false), nil, nil
			}
		}
	case pref.EnumKind:
		if f == GoTag {
			// Go tags use the numeric form of the enum value.
			if n, err := strconv.ParseInt(s, 10, 32); err == nil {
				if ev := evs.ByNumber(pref.EnumNumber(n)); ev != nil {
					return pref.ValueOf(ev.Number()), ev, nil
				}
			}
		} else {
			// Descriptor default_value use the enum identifier.
			ev := evs.ByName(pref.Name(s))
			if ev != nil {
				return pref.ValueOf(ev.Number()), ev, nil
			}
		}
	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
		if v, err := strconv.ParseInt(s, 10, 32); err == nil {
			return pref.ValueOf(int32(v)), nil, nil
		}
	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
		if v, err := strconv.ParseInt(s, 10, 64); err == nil {
			return pref.ValueOf(int64(v)), nil, nil
		}
	case pref.Uint32Kind, pref.Fixed32Kind:
		if v, err := strconv.ParseUint(s, 10, 32); err == nil {
			return pref.ValueOf(uint32(v)), nil, nil
		}
	case pref.Uint64Kind, pref.Fixed64Kind:
		if v, err := strconv.ParseUint(s, 10, 64); err == nil {
			return pref.ValueOf(uint64(v)), nil, nil
		}
	case pref.FloatKind, pref.DoubleKind:
		var v float64
		var err error
		switch s {
		case "-inf":
			v = math.Inf(-1)
		case "inf":
			v = math.Inf(+1)
		case "nan":
			v = math.NaN()
		default:
			v, err = strconv.ParseFloat(s, 64)
		}
		if err == nil {
			if k == pref.FloatKind {
				return pref.ValueOf(float32(v)), nil, nil
			} else {
				return pref.ValueOf(float64(v)), nil, nil
			}
		}
	case pref.StringKind:
		// String values are already unescaped and can be used as is.
		return pref.ValueOf(s), nil, nil
	case pref.BytesKind:
		if b, ok := unmarshalBytes(s); ok {
			return pref.ValueOf(b), nil, nil
		}
	}
	return pref.Value{}, nil, errors.New("could not parse value for %v: %q", k, s)
}

// Marshal serializes v as the default string according to the given kind k.
// When specifying the Descriptor format for an enum kind, the associated
// enum value descriptor must be provided.
func Marshal(v pref.Value, ev pref.EnumValueDescriptor, k pref.Kind, f Format) (string, error) {
	switch k {
	case pref.BoolKind:
		if f == GoTag {
			if v.Bool() {
				return "1", nil
			} else {
				return "0", nil
			}
		} else {
			if v.Bool() {
				return "true", nil
			} else {
				return "false", nil
			}
		}
	case pref.EnumKind:
		if f == GoTag {
			return strconv.FormatInt(int64(v.Enum()), 10), nil
		} else {
			return string(ev.Name()), nil
		}
	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind, pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
		return strconv.FormatInt(v.Int(), 10), nil
	case pref.Uint32Kind, pref.Fixed32Kind, pref.Uint64Kind, pref.Fixed64Kind:
		return strconv.FormatUint(v.Uint(), 10), nil
	case pref.FloatKind, pref.DoubleKind:
		f := v.Float()
		switch {
		case math.IsInf(f, -1):
			return "-inf", nil
		case math.IsInf(f, +1):
			return "inf", nil
		case math.IsNaN(f):
			return "nan", nil
		default:
			if k == pref.FloatKind {
				return strconv.FormatFloat(f, 'g', -1, 32), nil
			} else {
				return strconv.FormatFloat(f, 'g', -1, 64), nil
			}
		}
	case pref.StringKind:
		// String values are serialized as is without any escaping.
		return v.String(), nil
	case pref.BytesKind:
		if s, ok := marshalBytes(v.Bytes()); ok {
			return s, nil
		}
	}
	return "", errors.New("could not format value for %v: %v", k, v)
}

// unmarshalBytes deserializes bytes by applying C unescaping.
func unmarshalBytes(s string) ([]byte, bool) {
	// Bytes values use the same escaping as the text format,
	// however they lack the surrounding double quotes.
	// TODO: Export unmarshalString in the text package to avoid this hack.
	v, err := ptext.Unmarshal([]byte(`["` + s + `"]:0`))
	if err == nil && len(v.Message()) == 1 {
		s := v.Message()[0][0].String()
		return []byte(s), true
	}
	return nil, false
}

// marshalBytes serializes bytes by using C escaping.
// To match the exact output of protoc, this is identical to the
// CEscape function in strutil.cc of the protoc source code.
func marshalBytes(b []byte) (string, bool) {
	var s []byte
	for _, c := range b {
		switch c {
		case '\n':
			s = append(s, `\n`...)
		case '\r':
			s = append(s, `\r`...)
		case '\t':
			s = append(s, `\t`...)
		case '"':
			s = append(s, `\"`...)
		case '\'':
			s = append(s, `\'`...)
		case '\\':
			s = append(s, `\\`...)
		default:
			if printableASCII := c >= 0x20 && c <= 0x7e; printableASCII {
				s = append(s, c)
			} else {
				s = append(s, fmt.Sprintf(`\%03o`, c)...)
			}
		}
	}
	return string(s), true
}
