// Copyright 2024 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 filedesc

import (
	"fmt"

	"google.golang.org/protobuf/encoding/protowire"
	"google.golang.org/protobuf/internal/editiondefaults"
	"google.golang.org/protobuf/internal/genid"
	"google.golang.org/protobuf/reflect/protoreflect"
)

var defaultsCache = make(map[Edition]EditionFeatures)
var defaultsKeys = []Edition{}

func init() {
	unmarshalEditionDefaults(editiondefaults.Defaults)
	SurrogateProto2.L1.EditionFeatures = getFeaturesFor(EditionProto2)
	SurrogateProto3.L1.EditionFeatures = getFeaturesFor(EditionProto3)
	SurrogateEdition2023.L1.EditionFeatures = getFeaturesFor(Edition2023)
}

func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures {
	for len(b) > 0 {
		num, _, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch num {
		case genid.GoFeatures_LegacyUnmarshalJsonEnum_field_number:
			v, m := protowire.ConsumeVarint(b)
			b = b[m:]
			parent.GenerateLegacyUnmarshalJSON = protowire.DecodeBool(v)
		case genid.GoFeatures_ApiLevel_field_number:
			v, m := protowire.ConsumeVarint(b)
			b = b[m:]
			parent.APILevel = int(v)
		case genid.GoFeatures_StripEnumPrefix_field_number:
			v, m := protowire.ConsumeVarint(b)
			b = b[m:]
			parent.StripEnumPrefix = int(v)
		default:
			panic(fmt.Sprintf("unkown field number %d while unmarshalling GoFeatures", num))
		}
	}
	return parent
}

func unmarshalFeatureSet(b []byte, parent EditionFeatures) EditionFeatures {
	for len(b) > 0 {
		num, typ, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case genid.FeatureSet_FieldPresence_field_number:
				parent.IsFieldPresence = v == genid.FeatureSet_EXPLICIT_enum_value || v == genid.FeatureSet_LEGACY_REQUIRED_enum_value
				parent.IsLegacyRequired = v == genid.FeatureSet_LEGACY_REQUIRED_enum_value
			case genid.FeatureSet_EnumType_field_number:
				parent.IsOpenEnum = v == genid.FeatureSet_OPEN_enum_value
			case genid.FeatureSet_RepeatedFieldEncoding_field_number:
				parent.IsPacked = v == genid.FeatureSet_PACKED_enum_value
			case genid.FeatureSet_Utf8Validation_field_number:
				parent.IsUTF8Validated = v == genid.FeatureSet_VERIFY_enum_value
			case genid.FeatureSet_MessageEncoding_field_number:
				parent.IsDelimitedEncoded = v == genid.FeatureSet_DELIMITED_enum_value
			case genid.FeatureSet_JsonFormat_field_number:
				parent.IsJSONCompliant = v == genid.FeatureSet_ALLOW_enum_value
			default:
				panic(fmt.Sprintf("unkown field number %d while unmarshalling FeatureSet", num))
			}
		case protowire.BytesType:
			v, m := protowire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case genid.FeatureSet_Go_ext_number:
				parent = unmarshalGoFeature(v, parent)
			}
		}
	}

	return parent
}

func featuresFromParentDesc(parentDesc protoreflect.Descriptor) EditionFeatures {
	var parentFS EditionFeatures
	switch p := parentDesc.(type) {
	case *File:
		parentFS = p.L1.EditionFeatures
	case *Message:
		parentFS = p.L1.EditionFeatures
	default:
		panic(fmt.Sprintf("unknown parent type %T", parentDesc))
	}
	return parentFS
}

func unmarshalEditionDefault(b []byte) {
	var ed Edition
	var fs EditionFeatures
	for len(b) > 0 {
		num, typ, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch typ {
		case protowire.VarintType:
			v, m := protowire.ConsumeVarint(b)
			b = b[m:]
			switch num {
			case genid.FeatureSetDefaults_FeatureSetEditionDefault_Edition_field_number:
				ed = Edition(v)
			}
		case protowire.BytesType:
			v, m := protowire.ConsumeBytes(b)
			b = b[m:]
			switch num {
			case genid.FeatureSetDefaults_FeatureSetEditionDefault_FixedFeatures_field_number:
				fs = unmarshalFeatureSet(v, fs)
			case genid.FeatureSetDefaults_FeatureSetEditionDefault_OverridableFeatures_field_number:
				fs = unmarshalFeatureSet(v, fs)
			}
		}
	}
	defaultsCache[ed] = fs
	defaultsKeys = append(defaultsKeys, ed)
}

func unmarshalEditionDefaults(b []byte) {
	for len(b) > 0 {
		num, _, n := protowire.ConsumeTag(b)
		b = b[n:]
		switch num {
		case genid.FeatureSetDefaults_Defaults_field_number:
			def, m := protowire.ConsumeBytes(b)
			b = b[m:]
			unmarshalEditionDefault(def)
		case genid.FeatureSetDefaults_MinimumEdition_field_number,
			genid.FeatureSetDefaults_MaximumEdition_field_number:
			// We don't care about the minimum and maximum editions. If the
			// edition we are looking for later on is not in the cache we know
			// it is outside of the range between minimum and maximum edition.
			_, m := protowire.ConsumeVarint(b)
			b = b[m:]
		default:
			panic(fmt.Sprintf("unkown field number %d while unmarshalling EditionDefault", num))
		}
	}
}

func getFeaturesFor(ed Edition) EditionFeatures {
	match := EditionUnknown
	for _, key := range defaultsKeys {
		if key > ed {
			break
		}
		match = key
	}
	if match == EditionUnknown {
		panic(fmt.Sprintf("unsupported edition: %v", ed))
	}
	return defaultsCache[match]
}
