// 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 impl

import (
	"container/list"
	"reflect"
	"sort"

	"github.com/golang/protobuf/v2/internal/encoding/wire"
	pref "github.com/golang/protobuf/v2/reflect/protoreflect"
)

func makeLegacyUnknownFieldsFunc(t reflect.Type) func(p *messageDataType) pref.UnknownFields {
	fu, ok := t.FieldByName("XXX_unrecognized")
	if !ok || fu.Type != bytesType {
		return nil
	}
	fieldOffset := offsetOf(fu)
	unkFunc := func(p *messageDataType) pref.UnknownFields {
		rv := p.p.apply(fieldOffset).asType(bytesType)
		return (*legacyUnknownBytes)(rv.Interface().(*[]byte))
	}
	extFunc := makeLegacyExtensionMapFunc(t)
	if extFunc != nil {
		return func(p *messageDataType) pref.UnknownFields {
			return &legacyUnknownBytesAndExtensionMap{
				unkFunc(p), extFunc(p), p.mi.Desc.ExtensionRanges(),
			}
		}
	}
	return unkFunc
}

// legacyUnknownBytesAndExtensionMap is a wrapper around both XXX_unrecognized
// and also the extension field map.
type legacyUnknownBytesAndExtensionMap struct {
	u pref.UnknownFields
	x legacyExtensionIface
	r pref.FieldRanges
}

func (fs *legacyUnknownBytesAndExtensionMap) Len() int {
	n := fs.u.Len()
	fs.x.Range(func(_ pref.FieldNumber, x legacyExtensionEntry) bool {
		if len(x.raw) > 0 {
			n++
		}
		return true
	})
	return n
}

func (fs *legacyUnknownBytesAndExtensionMap) Get(num pref.FieldNumber) (raw pref.RawFields) {
	if fs.r.Has(num) {
		return fs.x.Get(num).raw
	}
	return fs.u.Get(num)
}

func (fs *legacyUnknownBytesAndExtensionMap) Set(num pref.FieldNumber, raw pref.RawFields) {
	if fs.r.Has(num) {
		x := fs.x.Get(num)
		x.raw = raw
		fs.x.Set(num, x)
		return
	}
	fs.u.Set(num, raw)
}

func (fs *legacyUnknownBytesAndExtensionMap) Range(f func(pref.FieldNumber, pref.RawFields) bool) {
	// Range over unknown fields not in the extension range.
	// Create a closure around f to capture whether iteration terminated early.
	var stop bool
	fs.u.Range(func(n pref.FieldNumber, b pref.RawFields) bool {
		stop = stop || !f(n, b)
		return !stop
	})
	if stop {
		return
	}

	// Range over unknown fields in the extension range in ascending order
	// to ensure protoreflect.UnknownFields.Range remains deterministic.
	type entry struct {
		num pref.FieldNumber
		raw pref.RawFields
	}
	var xs []entry
	fs.x.Range(func(n pref.FieldNumber, x legacyExtensionEntry) bool {
		if len(x.raw) > 0 {
			xs = append(xs, entry{n, x.raw})
		}
		return true
	})
	sort.Slice(xs, func(i, j int) bool { return xs[i].num < xs[j].num })
	for _, x := range xs {
		if !f(x.num, x.raw) {
			return
		}
	}
}

func (fs *legacyUnknownBytesAndExtensionMap) IsSupported() bool {
	return true
}

// legacyUnknownBytes is a wrapper around XXX_unrecognized that implements
// the protoreflect.UnknownFields interface. This is challenging since we are
// limited to a []byte, so we do not have much flexibility in the choice
// of data structure that would have been ideal.
type legacyUnknownBytes []byte

func (fs *legacyUnknownBytes) Len() int {
	// Runtime complexity: O(n)
	b := *fs
	m := map[pref.FieldNumber]bool{}
	for len(b) > 0 {
		num, _, n := wire.ConsumeField(b)
		m[num] = true
		b = b[n:]
	}
	return len(m)
}

func (fs *legacyUnknownBytes) Get(num pref.FieldNumber) (raw pref.RawFields) {
	// Runtime complexity: O(n)
	b := *fs
	for len(b) > 0 {
		num2, _, n := wire.ConsumeField(b)
		if num == num2 {
			raw = append(raw, b[:n]...)
		}
		b = b[n:]
	}
	return raw
}

func (fs *legacyUnknownBytes) Set(num pref.FieldNumber, raw pref.RawFields) {
	num2, _, _ := wire.ConsumeTag(raw)
	if len(raw) > 0 && (!raw.IsValid() || num != num2) {
		panic("invalid raw fields")
	}

	// Remove all current fields of num.
	// Runtime complexity: O(n)
	b := *fs
	out := (*fs)[:0]
	for len(b) > 0 {
		num2, _, n := wire.ConsumeField(b)
		if num != num2 {
			out = append(out, b[:n]...)
		}
		b = b[n:]
	}
	*fs = out

	// Append new fields of num.
	*fs = append(*fs, raw...)
}

func (fs *legacyUnknownBytes) Range(f func(pref.FieldNumber, pref.RawFields) bool) {
	type entry struct {
		num pref.FieldNumber
		raw pref.RawFields
	}

	// Collect up a list of all the raw fields.
	// We preserve the order such that the latest encountered fields
	// are presented at the end.
	//
	// Runtime complexity: O(n)
	b := *fs
	l := list.New()
	m := map[pref.FieldNumber]*list.Element{}
	for len(b) > 0 {
		num, _, n := wire.ConsumeField(b)
		if e, ok := m[num]; ok {
			x := e.Value.(*entry)
			x.raw = append(x.raw, b[:n]...)
			l.MoveToBack(e)
		} else {
			x := &entry{num: num}
			x.raw = append(x.raw, b[:n]...)
			m[num] = l.PushBack(x)
		}
		b = b[n:]
	}

	// Iterate over all the raw fields.
	// This ranges over a snapshot of the current state such that mutations
	// while ranging are not observable.
	//
	// Runtime complexity: O(n)
	for e := l.Front(); e != nil; e = e.Next() {
		x := e.Value.(*entry)
		if !f(x.num, x.raw) {
			return
		}
	}
}

func (fs *legacyUnknownBytes) IsSupported() bool {
	return true
}
