// Copyright 2020 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.

//go:build goexperiment.jsonv2

package json

import (
	"bytes"
	"cmp"
	"errors"
	"fmt"
	"math"
	"math/bits"
	"reflect"
	"strconv"
	"strings"
	"time"

	"encoding/json/internal"
	"encoding/json/internal/jsonflags"
	"encoding/json/internal/jsonopts"
	"encoding/json/internal/jsonwire"
	"encoding/json/jsontext"
)

var (
	timeDurationType = reflect.TypeFor[time.Duration]()
	timeTimeType     = reflect.TypeFor[time.Time]()
)

func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
	// Ideally, time types would implement MarshalerTo and UnmarshalerFrom,
	// but that would incur a dependency on package json from package time.
	// Given how widely used time is, it is more acceptable that we incur a
	// dependency on time from json.
	//
	// Injecting the arshaling functionality like this will not be identical
	// to actually declaring methods on the time types since embedding of the
	// time types will not be able to forward this functionality.
	switch t {
	case timeDurationType:
		fncs.nonDefault = true
		marshalNano := fncs.marshal
		fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
			xe := export.Encoder(enc)
			var m durationArshaler
			if mo.Flags.Has(jsonflags.FormatTag) {
				if !m.initFormat(mo.Format) {
					return newInvalidFormatError(enc, t)
				}
			} else if mo.Flags.Get(jsonflags.FormatDurationAsNano) {
				return marshalNano(enc, va, mo)
			} else {
				// TODO(https://go.dev/issue/71631): Decide on default duration representation.
				var workaround string
				if mo.Flags.Get(jsonflags.FormatTagSupported) {
					workaround = "; specify an explicit format"
				}
				return newMarshalErrorBefore(enc, t, errors.New("no default representation"+workaround))
			}
			if mo.Flags.Get(jsonflags.StringTag) && !m.isNumeric() && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
				return newMarshalErrorBefore(enc, t, errInvalidStringTag)
			}

			m.td, _ = reflect.TypeAssert[time.Duration](va.Value)
			k := stringOrNumberKind(!m.isNumeric() || xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag))
			if err := xe.AppendRaw(k, true, m.appendMarshal); err != nil {
				if !isSyntacticError(err) && !export.IsIOError(err) {
					err = newMarshalErrorBefore(enc, t, err)
				}
				return err
			}
			return nil
		}
		unmarshalNano := fncs.unmarshal
		fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error {
			xd := export.Decoder(dec)
			var u durationArshaler
			if uo.Flags.Has(jsonflags.FormatTag) {
				if !u.initFormat(uo.Format) {
					return newInvalidFormatError(dec, t)
				}
			} else if uo.Flags.Get(jsonflags.FormatDurationAsNano) {
				return unmarshalNano(dec, va, uo)
			} else {
				// TODO(https://go.dev/issue/71631): Decide on default duration representation.
				var workaround string
				if uo.Flags.Get(jsonflags.FormatTagSupported) {
					workaround = "; specify an explicit format"
				}
				return newUnmarshalErrorBeforeWithSkipping(dec, t, errors.New("no default representation"+workaround))
			}
			if uo.Flags.Get(jsonflags.StringTag) && !u.isNumeric() && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
				return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
			}

			stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
			var flags jsonwire.ValueFlags
			td, _ := reflect.TypeAssert[*time.Duration](va.Addr())
			val, err := xd.ReadValue(&flags)
			if err != nil {
				return err
			}
			switch k := val.Kind(); k {
			case 'n':
				if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
					*td = time.Duration(0)
				}
				return nil
			case '"':
				if !stringify {
					break
				}
				val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
				if err := u.unmarshal(val); err != nil {
					return newUnmarshalErrorAfter(dec, t, err)
				}
				*td = u.td
				return nil
			case '0':
				if stringify {
					break
				}
				if err := u.unmarshal(val); err != nil {
					return newUnmarshalErrorAfter(dec, t, err)
				}
				*td = u.td
				return nil
			}
			return newUnmarshalErrorAfter(dec, t, nil)
		}
	case timeTimeType:
		fncs.nonDefault = true
		fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) (err error) {
			xe := export.Encoder(enc)
			var m timeArshaler
			if mo.Flags.Has(jsonflags.FormatTag) {
				if !m.initFormat(mo.Format) {
					return newInvalidFormatError(enc, t)
				}
			}
			if mo.Flags.Get(jsonflags.StringTag) && !m.isNumeric() && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
				return newMarshalErrorBefore(enc, t, errInvalidStringTag)
			}

			m.tt, _ = reflect.TypeAssert[time.Time](va.Value)
			k := stringOrNumberKind(!m.isNumeric() || xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag))
			if err := xe.AppendRaw(k, !m.hasCustomFormat(), m.appendMarshal); err != nil {
				if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
					return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalJSON") // unlike unmarshal, always wrapped
				}
				if !isSyntacticError(err) && !export.IsIOError(err) {
					err = newMarshalErrorBefore(enc, t, err)
				}
				return err
			}
			return nil
		}
		fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) (err error) {
			xd := export.Decoder(dec)
			var u timeArshaler
			if uo.Flags.Has(jsonflags.FormatTag) {
				if !u.initFormat(uo.Format) {
					return newInvalidFormatError(dec, t)
				}
			} else if uo.Flags.Get(jsonflags.ParseTimeWithLooseRFC3339) {
				u.looseRFC3339 = true
			}
			if uo.Flags.Get(jsonflags.StringTag) && !u.isNumeric() && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
				return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag)
			}

			stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)
			var flags jsonwire.ValueFlags
			tt, _ := reflect.TypeAssert[*time.Time](va.Addr())
			val, err := xd.ReadValue(&flags)
			if err != nil {
				return err
			}
			switch k := val.Kind(); k {
			case 'n':
				if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
					*tt = time.Time{}
				}
				return nil
			case '"':
				if !stringify {
					break
				}
				val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
				if err := u.unmarshal(val); err != nil {
					if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
						return err // unlike marshal, never wrapped
					}
					return newUnmarshalErrorAfter(dec, t, err)
				}
				*tt = u.tt
				return nil
			case '0':
				if stringify {
					break
				}
				if err := u.unmarshal(val); err != nil {
					if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
						return err // unlike marshal, never wrapped
					}
					return newUnmarshalErrorAfter(dec, t, err)
				}
				*tt = u.tt
				return nil
			}
			return newUnmarshalErrorAfter(dec, t, nil)
		}
	}
	return fncs
}

type durationArshaler struct {
	td time.Duration

	// base records the representation where:
	//   - 0 uses time.Duration.String
	//   - 1e0, 1e3, 1e6, or 1e9 use a decimal encoding of the duration as
	//     nanoseconds, microseconds, milliseconds, or seconds.
	//   - 8601 uses ISO 8601
	base uint64
}

func (a *durationArshaler) initFormat(format string) (ok bool) {
	switch format {
	case "units":
		a.base = 0
	case "sec":
		a.base = 1e9
	case "milli":
		a.base = 1e6
	case "micro":
		a.base = 1e3
	case "nano":
		a.base = 1e0
	case "iso8601":
		a.base = 8601
	default:
		return false
	}
	return true
}

func (a *durationArshaler) isNumeric() bool {
	return a.base != 0 && a.base != 8601
}

func (a *durationArshaler) appendMarshal(b []byte) ([]byte, error) {
	switch a.base {
	case 0:
		return append(b, a.td.String()...), nil
	case 8601:
		return appendDurationISO8601(b, a.td), nil
	default:
		return appendDurationBase10(b, a.td, a.base), nil
	}
}

func (a *durationArshaler) unmarshal(b []byte) (err error) {
	switch a.base {
	case 0:
		a.td, err = time.ParseDuration(string(b))
	case 8601:
		a.td, err = parseDurationISO8601(b)
	default:
		a.td, err = parseDurationBase10(b, a.base)
	}
	return err
}

type timeArshaler struct {
	tt time.Time

	// base records the representation where:
	//   - 0 uses RFC 3339 encoding of the timestamp
	//   - 1e0, 1e3, 1e6, or 1e9 use a decimal encoding of the timestamp as
	//     seconds, milliseconds, microseconds, or nanoseconds since Unix epoch.
	//   - math.MaxUint uses time.Time.Format to encode the timestamp
	base   uint64
	format string // time format passed to time.Parse

	looseRFC3339 bool
}

func (a *timeArshaler) initFormat(format string) bool {
	// We assume that an exported constant in the time package will
	// always start with an uppercase ASCII letter.
	if len(format) == 0 {
		return false
	}
	a.base = math.MaxUint // implies custom format
	if c := format[0]; !('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') {
		a.format = format
		return true
	}
	switch format {
	case "ANSIC":
		a.format = time.ANSIC
	case "UnixDate":
		a.format = time.UnixDate
	case "RubyDate":
		a.format = time.RubyDate
	case "RFC822":
		a.format = time.RFC822
	case "RFC822Z":
		a.format = time.RFC822Z
	case "RFC850":
		a.format = time.RFC850
	case "RFC1123":
		a.format = time.RFC1123
	case "RFC1123Z":
		a.format = time.RFC1123Z
	case "RFC3339":
		a.base = 0
		a.format = time.RFC3339
	case "RFC3339Nano":
		a.base = 0
		a.format = time.RFC3339Nano
	case "Kitchen":
		a.format = time.Kitchen
	case "Stamp":
		a.format = time.Stamp
	case "StampMilli":
		a.format = time.StampMilli
	case "StampMicro":
		a.format = time.StampMicro
	case "StampNano":
		a.format = time.StampNano
	case "DateTime":
		a.format = time.DateTime
	case "DateOnly":
		a.format = time.DateOnly
	case "TimeOnly":
		a.format = time.TimeOnly
	case "unix":
		a.base = 1e0
	case "unixmilli":
		a.base = 1e3
	case "unixmicro":
		a.base = 1e6
	case "unixnano":
		a.base = 1e9
	default:
		// Reject any Go identifier in case new constants are supported.
		if strings.TrimFunc(format, isLetterOrDigit) == "" {
			return false
		}
		a.format = format
	}
	return true
}

func (a *timeArshaler) isNumeric() bool {
	return int(a.base) > 0
}

func (a *timeArshaler) hasCustomFormat() bool {
	return a.base == math.MaxUint
}

func (a *timeArshaler) appendMarshal(b []byte) ([]byte, error) {
	switch a.base {
	case 0:
		format := cmp.Or(a.format, time.RFC3339Nano)
		n0 := len(b)
		b = a.tt.AppendFormat(b, format)
		// Not all Go timestamps can be represented as valid RFC 3339.
		// Explicitly check for these edge cases.
		// See https://go.dev/issue/4556 and https://go.dev/issue/54580.
		switch b := b[n0:]; {
		case b[len("9999")] != '-': // year must be exactly 4 digits wide
			return b, errors.New("year outside of range [0,9999]")
		case b[len(b)-1] != 'Z':
			c := b[len(b)-len("Z07:00")]
			if ('0' <= c && c <= '9') || parseDec2(b[len(b)-len("07:00"):]) >= 24 {
				return b, errors.New("timezone hour outside of range [0,23]")
			}
		}
		return b, nil
	case math.MaxUint:
		return a.tt.AppendFormat(b, a.format), nil
	default:
		return appendTimeUnix(b, a.tt, a.base), nil
	}
}

func (a *timeArshaler) unmarshal(b []byte) (err error) {
	switch a.base {
	case 0:
		// Use time.Time.UnmarshalText to avoid possible string allocation.
		if err := a.tt.UnmarshalText(b); err != nil {
			return err
		}
		// TODO(https://go.dev/issue/57912):
		// RFC 3339 specifies the grammar for a valid timestamp.
		// However, the parsing functionality in "time" is too loose and
		// incorrectly accepts invalid timestamps as valid.
		// Remove these manual checks when "time" checks it for us.
		newParseError := func(layout, value, layoutElem, valueElem, message string) error {
			return &time.ParseError{Layout: layout, Value: value, LayoutElem: layoutElem, ValueElem: valueElem, Message: message}
		}
		switch {
		case a.looseRFC3339:
			return nil
		case b[len("2006-01-02T")+1] == ':': // hour must be two digits
			return newParseError(time.RFC3339, string(b), "15", string(b[len("2006-01-02T"):][:1]), "")
		case b[len("2006-01-02T15:04:05")] == ',': // sub-second separator must be a period
			return newParseError(time.RFC3339, string(b), ".", ",", "")
		case b[len(b)-1] != 'Z':
			switch {
			case parseDec2(b[len(b)-len("07:00"):]) >= 24: // timezone hour must be in range
				return newParseError(time.RFC3339, string(b), "Z07:00", string(b[len(b)-len("Z07:00"):]), ": timezone hour out of range")
			case parseDec2(b[len(b)-len("00"):]) >= 60: // timezone minute must be in range
				return newParseError(time.RFC3339, string(b), "Z07:00", string(b[len(b)-len("Z07:00"):]), ": timezone minute out of range")
			}
		}
		return nil
	case math.MaxUint:
		a.tt, err = time.Parse(a.format, string(b))
		return err
	default:
		a.tt, err = parseTimeUnix(b, a.base)
		return err
	}
}

// appendDurationBase10 appends d formatted as a decimal fractional number,
// where pow10 is a power-of-10 used to scale down the number.
func appendDurationBase10(b []byte, d time.Duration, pow10 uint64) []byte {
	b, n := mayAppendDurationSign(b, d)            // append sign
	whole, frac := bits.Div64(0, n, uint64(pow10)) // compute whole and frac fields
	b = strconv.AppendUint(b, whole, 10)           // append whole field
	return appendFracBase10(b, frac, pow10)        // append frac field
}

// parseDurationBase10 parses d from a decimal fractional number,
// where pow10 is a power-of-10 used to scale up the number.
func parseDurationBase10(b []byte, pow10 uint64) (time.Duration, error) {
	suffix, neg := consumeSign(b, false)                     // consume sign
	wholeBytes, fracBytes := bytesCutByte(suffix, '.', true) // consume whole and frac fields
	whole, okWhole := jsonwire.ParseUint(wholeBytes)         // parse whole field; may overflow
	frac, okFrac := parseFracBase10(fracBytes, pow10)        // parse frac field
	hi, lo := bits.Mul64(whole, uint64(pow10))               // overflow if hi > 0
	sum, co := bits.Add64(lo, uint64(frac), 0)               // overflow if co > 0
	switch d := mayApplyDurationSign(sum, neg); {            // overflow if neg != (d < 0)
	case (!okWhole && whole != math.MaxUint64) || !okFrac:
		return 0, fmt.Errorf("invalid duration %q: %w", b, strconv.ErrSyntax)
	case !okWhole || hi > 0 || co > 0 || neg != (d < 0):
		return 0, fmt.Errorf("invalid duration %q: %w", b, strconv.ErrRange)
	default:
		return d, nil
	}
}

// appendDurationISO8601 appends an ISO 8601 duration with a restricted grammar,
// where leading and trailing zeroes and zero-value designators are omitted.
// It only uses hour, minute, and second designators since ISO 8601 defines
// those as being "accurate", while year, month, week, and day are "nominal".
func appendDurationISO8601(b []byte, d time.Duration) []byte {
	if d == 0 {
		return append(b, "PT0S"...)
	}
	b, n := mayAppendDurationSign(b, d)
	b = append(b, "PT"...)
	n, nsec := bits.Div64(0, n, 1e9)  // compute nsec field
	n, sec := bits.Div64(0, n, 60)    // compute sec field
	hour, min := bits.Div64(0, n, 60) // compute hour and min fields
	if hour > 0 {
		b = append(strconv.AppendUint(b, hour, 10), 'H')
	}
	if min > 0 {
		b = append(strconv.AppendUint(b, min, 10), 'M')
	}
	if sec > 0 || nsec > 0 {
		b = append(appendFracBase10(strconv.AppendUint(b, sec, 10), nsec, 1e9), 'S')
	}
	return b
}

// daysPerYear is the exact average number of days in a year according to
// the Gregorian calendar, which has an extra day each year that is
// a multiple of 4, unless it is evenly divisible by 100 but not by 400.
// This does not take into account leap seconds, which are not deterministic.
const daysPerYear = 365.2425

var errInaccurateDateUnits = errors.New("inaccurate year, month, week, or day units")

// parseDurationISO8601 parses a duration according to ISO 8601-1:2019,
// section 5.5.2.2 and 5.5.2.3 with the following restrictions or extensions:
//
//   - A leading minus sign is permitted for negative duration according
//     to ISO 8601-2:2019, section 4.4.1.9. We do not permit negative values
//     for each "time scale component", which is permitted by section 4.4.1.1,
//     but rarely supported by parsers.
//
//   - A leading plus sign is permitted (and ignored).
//     This is not required by ISO 8601, but not forbidden either.
//     There is some precedent for this as it is supported by the principle of
//     duration arithmetic as specified in ISO 8601-2-2019, section 14.1.
//     Of note, the JavaScript grammar for ISO 8601 permits a leading plus sign.
//
//   - A fractional value is only permitted for accurate units
//     (i.e., hour, minute, and seconds) in the last time component,
//     which is permissible by ISO 8601-1:2019, section 5.5.2.3.
//
//   - Both periods ('.') and commas (',') are supported as the separator
//     between the integer part and fraction part of a number,
//     as specified in ISO 8601-1:2019, section 3.2.6.
//     While ISO 8601 recommends comma as the default separator,
//     most formatters use a period.
//
//   - Leading zeros are ignored. This is not required by ISO 8601,
//     but also not forbidden by the standard. Many parsers support this.
//
//   - Lowercase designators are supported. This is not required by ISO 8601,
//     but also not forbidden by the standard. Many parsers support this.
//
// If the nominal units of year, month, week, or day are present,
// this produces a best-effort value and also reports [errInaccurateDateUnits].
//
// The accepted grammar is identical to JavaScript's Duration:
//
//	https://tc39.es/proposal-temporal/#prod-Duration
//
// We follow JavaScript's grammar as JSON itself is derived from JavaScript.
// The Temporal.Duration.toJSON method is guaranteed to produce an output
// that can be parsed by this function so long as arithmetic in JavaScript
// does not use a largestUnit value higher than "hours" (which is the default).
// Even if it does, this will do a best-effort parsing with inaccurate units,
// but report [errInaccurateDateUnits].
func parseDurationISO8601(b []byte) (time.Duration, error) {
	var invalid, overflow, inaccurate, sawFrac bool
	var sumNanos, n, co uint64

	// cutBytes is like [bytes.Cut], but uses either c0 or c1 as the separator.
	cutBytes := func(b []byte, c0, c1 byte) (prefix, suffix []byte, ok bool) {
		for i, c := range b {
			if c == c0 || c == c1 {
				return b[:i], b[i+1:], true
			}
		}
		return b, nil, false
	}

	// mayParseUnit attempts to parse another date or time number
	// identified by the desHi and desLo unit characters.
	// If the part is absent for current unit, it returns b as is.
	mayParseUnit := func(b []byte, desHi, desLo byte, unit time.Duration) []byte {
		number, suffix, ok := cutBytes(b, desHi, desLo)
		if !ok || sawFrac {
			return b // designator is not present or already saw fraction, which can only be in the last component
		}

		// Parse the number.
		// A fraction is allowed for the accurate units in the last part.
		whole, frac, ok := cutBytes(number, '.', ',')
		if ok {
			sawFrac = true
			invalid = invalid || len(frac) == len("") || unit > time.Hour
			if unit == time.Second {
				n, ok = parsePaddedBase10(frac, uint64(time.Second))
				invalid = invalid || !ok
			} else {
				f, err := strconv.ParseFloat("0."+string(frac), 64)
				invalid = invalid || err != nil || len(bytes.Trim(frac[len("."):], "0123456789")) > 0
				n = uint64(math.Round(f * float64(unit))) // never overflows since f is within [0..1]
			}
			sumNanos, co = bits.Add64(sumNanos, n, 0) // overflow if co > 0
			overflow = overflow || co > 0
		}
		for len(whole) > 1 && whole[0] == '0' {
			whole = whole[len("0"):] // trim leading zeros
		}
		n, ok := jsonwire.ParseUint(whole)         // overflow if !ok && MaxUint64
		hi, lo := bits.Mul64(n, uint64(unit))      // overflow if hi > 0
		sumNanos, co = bits.Add64(sumNanos, lo, 0) // overflow if co > 0
		invalid = invalid || (!ok && n != math.MaxUint64)
		overflow = overflow || (!ok && n == math.MaxUint64) || hi > 0 || co > 0
		inaccurate = inaccurate || unit > time.Hour
		return suffix
	}

	suffix, neg := consumeSign(b, true)
	prefix, suffix, okP := cutBytes(suffix, 'P', 'p')
	durDate, durTime, okT := cutBytes(suffix, 'T', 't')
	invalid = invalid || len(prefix) > 0 || !okP || (okT && len(durTime) == 0) || len(durDate)+len(durTime) == 0
	if len(durDate) > 0 { // nominal portion of the duration
		durDate = mayParseUnit(durDate, 'Y', 'y', time.Duration(daysPerYear*24*60*60*1e9))
		durDate = mayParseUnit(durDate, 'M', 'm', time.Duration(daysPerYear/12*24*60*60*1e9))
		durDate = mayParseUnit(durDate, 'W', 'w', time.Duration(7*24*60*60*1e9))
		durDate = mayParseUnit(durDate, 'D', 'd', time.Duration(24*60*60*1e9))
		invalid = invalid || len(durDate) > 0 // unknown elements
	}
	if len(durTime) > 0 { // accurate portion of the duration
		durTime = mayParseUnit(durTime, 'H', 'h', time.Duration(60*60*1e9))
		durTime = mayParseUnit(durTime, 'M', 'm', time.Duration(60*1e9))
		durTime = mayParseUnit(durTime, 'S', 's', time.Duration(1e9))
		invalid = invalid || len(durTime) > 0 // unknown elements
	}
	d := mayApplyDurationSign(sumNanos, neg)
	overflow = overflow || (neg != (d < 0) && d != 0) // overflows signed duration

	switch {
	case invalid:
		return 0, fmt.Errorf("invalid ISO 8601 duration %q: %w", b, strconv.ErrSyntax)
	case overflow:
		return 0, fmt.Errorf("invalid ISO 8601 duration %q: %w", b, strconv.ErrRange)
	case inaccurate:
		return d, fmt.Errorf("invalid ISO 8601 duration %q: %w", b, errInaccurateDateUnits)
	default:
		return d, nil
	}
}

// mayAppendDurationSign appends a negative sign if n is negative.
func mayAppendDurationSign(b []byte, d time.Duration) ([]byte, uint64) {
	if d < 0 {
		b = append(b, '-')
		d *= -1
	}
	return b, uint64(d)
}

// mayApplyDurationSign inverts n if neg is specified.
func mayApplyDurationSign(n uint64, neg bool) time.Duration {
	if neg {
		return -1 * time.Duration(n)
	} else {
		return +1 * time.Duration(n)
	}
}

// appendTimeUnix appends t formatted as a decimal fractional number,
// where pow10 is a power-of-10 used to scale up the number.
func appendTimeUnix(b []byte, t time.Time, pow10 uint64) []byte {
	sec, nsec := t.Unix(), int64(t.Nanosecond())
	if sec < 0 {
		b = append(b, '-')
		sec, nsec = negateSecNano(sec, nsec)
	}
	switch {
	case pow10 == 1e0: // fast case where units is in seconds
		b = strconv.AppendUint(b, uint64(sec), 10)
		return appendFracBase10(b, uint64(nsec), 1e9)
	case uint64(sec) < 1e9: // intermediate case where units is not seconds, but no overflow
		b = strconv.AppendUint(b, uint64(sec)*uint64(pow10)+uint64(uint64(nsec)/(1e9/pow10)), 10)
		return appendFracBase10(b, (uint64(nsec)*pow10)%1e9, 1e9)
	default: // slow case where units is not seconds and overflow would occur
		b = strconv.AppendUint(b, uint64(sec), 10)
		b = appendPaddedBase10(b, uint64(nsec)/(1e9/pow10), pow10)
		return appendFracBase10(b, (uint64(nsec)*pow10)%1e9, 1e9)
	}
}

// parseTimeUnix parses t formatted as a decimal fractional number,
// where pow10 is a power-of-10 used to scale down the number.
func parseTimeUnix(b []byte, pow10 uint64) (time.Time, error) {
	suffix, neg := consumeSign(b, false)                     // consume sign
	wholeBytes, fracBytes := bytesCutByte(suffix, '.', true) // consume whole and frac fields
	whole, okWhole := jsonwire.ParseUint(wholeBytes)         // parse whole field; may overflow
	frac, okFrac := parseFracBase10(fracBytes, 1e9/pow10)    // parse frac field
	var sec, nsec int64
	switch {
	case pow10 == 1e0: // fast case where units is in seconds
		sec = int64(whole) // check overflow later after negation
		nsec = int64(frac) // cannot overflow
	case okWhole: // intermediate case where units is not seconds, but no overflow
		sec = int64(whole / pow10)                     // check overflow later after negation
		nsec = int64((whole%pow10)*(1e9/pow10) + frac) // cannot overflow
	case !okWhole && whole == math.MaxUint64: // slow case where units is not seconds and overflow occurred
		width := int(math.Log10(float64(pow10)))                                // compute len(strconv.Itoa(pow10-1))
		whole, okWhole = jsonwire.ParseUint(wholeBytes[:len(wholeBytes)-width]) // parse the upper whole field
		mid, _ := parsePaddedBase10(wholeBytes[len(wholeBytes)-width:], pow10)  // parse the lower whole field
		sec = int64(whole)                                                      // check overflow later after negation
		nsec = int64(mid*(1e9/pow10) + frac)                                    // cannot overflow
	}
	if neg {
		sec, nsec = negateSecNano(sec, nsec)
	}
	switch t := time.Unix(sec, nsec).UTC(); {
	case (!okWhole && whole != math.MaxUint64) || !okFrac:
		return time.Time{}, fmt.Errorf("invalid time %q: %w", b, strconv.ErrSyntax)
	case !okWhole || neg != (t.Unix() < 0):
		return time.Time{}, fmt.Errorf("invalid time %q: %w", b, strconv.ErrRange)
	default:
		return t, nil
	}
}

// negateSecNano negates a Unix timestamp, where nsec must be within [0, 1e9).
func negateSecNano(sec, nsec int64) (int64, int64) {
	sec = ^sec               // twos-complement negation (i.e., -1*sec + 1)
	nsec = -nsec + 1e9       // negate nsec and add 1e9 (which is the extra +1 from sec negation)
	sec += int64(nsec / 1e9) // handle possible overflow of nsec if it started as zero
	nsec %= 1e9              // ensure nsec stays within [0, 1e9)
	return sec, nsec
}

// appendFracBase10 appends the fraction of n/max10,
// where max10 is a power-of-10 that is larger than n.
func appendFracBase10(b []byte, n, max10 uint64) []byte {
	if n == 0 {
		return b
	}
	return bytes.TrimRight(appendPaddedBase10(append(b, '.'), n, max10), "0")
}

// parseFracBase10 parses the fraction of n/max10,
// where max10 is a power-of-10 that is larger than n.
func parseFracBase10(b []byte, max10 uint64) (n uint64, ok bool) {
	switch {
	case len(b) == 0:
		return 0, true
	case len(b) < len(".0") || b[0] != '.':
		return 0, false
	}
	return parsePaddedBase10(b[len("."):], max10)
}

// appendPaddedBase10 appends a zero-padded encoding of n,
// where max10 is a power-of-10 that is larger than n.
func appendPaddedBase10(b []byte, n, max10 uint64) []byte {
	if n < max10/10 {
		// Formatting of n is shorter than log10(max10),
		// so add max10/10 to ensure the length is equal to log10(max10).
		i := len(b)
		b = strconv.AppendUint(b, n+max10/10, 10)
		b[i]-- // subtract the addition of max10/10
		return b
	}
	return strconv.AppendUint(b, n, 10)
}

// parsePaddedBase10 parses b as the zero-padded encoding of n,
// where max10 is a power-of-10 that is larger than n.
// Truncated suffix is treated as implicit zeros.
// Extended suffix is ignored, but verified to contain only digits.
func parsePaddedBase10(b []byte, max10 uint64) (n uint64, ok bool) {
	pow10 := uint64(1)
	for pow10 < max10 {
		n *= 10
		if len(b) > 0 {
			if b[0] < '0' || '9' < b[0] {
				return n, false
			}
			n += uint64(b[0] - '0')
			b = b[1:]
		}
		pow10 *= 10
	}
	if len(b) > 0 && len(bytes.TrimRight(b, "0123456789")) > 0 {
		return n, false // trailing characters are not digits
	}
	return n, true
}

// consumeSign consumes an optional leading negative or positive sign.
func consumeSign(b []byte, allowPlus bool) ([]byte, bool) {
	if len(b) > 0 {
		if b[0] == '-' {
			return b[len("-"):], true
		} else if b[0] == '+' && allowPlus {
			return b[len("+"):], false
		}
	}
	return b, false
}

// bytesCutByte is similar to bytes.Cut(b, []byte{c}),
// except c may optionally be included as part of the suffix.
func bytesCutByte(b []byte, c byte, include bool) ([]byte, []byte) {
	if i := bytes.IndexByte(b, c); i >= 0 {
		if include {
			return b[:i], b[i:]
		}
		return b[:i], b[i+1:]
	}
	return b, nil
}

// parseDec2 parses b as an unsigned, base-10, 2-digit number.
// The result is undefined if digits are not base-10.
func parseDec2(b []byte) byte {
	if len(b) < 2 {
		return 0
	}
	return 10*(b[0]-'0') + (b[1] - '0')
}
