// Copyright 2019 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 protodesc

import (
	"fmt"
	"os"
	"sync"

	"google.golang.org/protobuf/internal/editiondefaults"
	"google.golang.org/protobuf/internal/filedesc"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/types/descriptorpb"
	"google.golang.org/protobuf/types/gofeaturespb"
)

var defaults = &descriptorpb.FeatureSetDefaults{}
var defaultsCacheMu sync.Mutex
var defaultsCache = make(map[filedesc.Edition]*descriptorpb.FeatureSet)

func init() {
	err := proto.Unmarshal(editiondefaults.Defaults, defaults)
	if err != nil {
		fmt.Fprintf(os.Stderr, "unmarshal editions defaults: %v\n", err)
		os.Exit(1)
	}
}

func fromEditionProto(epb descriptorpb.Edition) filedesc.Edition {
	return filedesc.Edition(epb)
}

func toEditionProto(ed filedesc.Edition) descriptorpb.Edition {
	switch ed {
	case filedesc.EditionUnknown:
		return descriptorpb.Edition_EDITION_UNKNOWN
	case filedesc.EditionProto2:
		return descriptorpb.Edition_EDITION_PROTO2
	case filedesc.EditionProto3:
		return descriptorpb.Edition_EDITION_PROTO3
	case filedesc.Edition2023:
		return descriptorpb.Edition_EDITION_2023
	default:
		panic(fmt.Sprintf("unknown value for edition: %v", ed))
	}
}

func getFeatureSetFor(ed filedesc.Edition) *descriptorpb.FeatureSet {
	defaultsCacheMu.Lock()
	defer defaultsCacheMu.Unlock()
	if def, ok := defaultsCache[ed]; ok {
		return def
	}
	edpb := toEditionProto(ed)
	if defaults.GetMinimumEdition() > edpb || defaults.GetMaximumEdition() < edpb {
		// This should never happen protodesc.(FileOptions).New would fail when
		// initializing the file descriptor.
		// This most likely means the embedded defaults were not updated.
		fmt.Fprintf(os.Stderr, "internal error: unsupported edition %v (did you forget to update the embedded defaults (i.e. the bootstrap descriptor proto)?)\n", edpb)
		os.Exit(1)
	}
	fsed := defaults.GetDefaults()[0]
	// Using a linear search for now.
	// Editions are guaranteed to be sorted and thus we could use a binary search.
	// Given that there are only a handful of editions (with one more per year)
	// there is not much reason to use a binary search.
	for _, def := range defaults.GetDefaults() {
		if def.GetEdition() <= edpb {
			fsed = def
		} else {
			break
		}
	}
	fs := proto.Clone(fsed.GetFixedFeatures()).(*descriptorpb.FeatureSet)
	proto.Merge(fs, fsed.GetOverridableFeatures())
	defaultsCache[ed] = fs
	return fs
}

// mergeEditionFeatures merges the parent and child feature sets. This function
// should be used when initializing Go descriptors from descriptor protos which
// is why the parent is a filedesc.EditionsFeatures (Go representation) while
// the child is a descriptorproto.FeatureSet (protoc representation).
// Any feature set by the child overwrites what is set by the parent.
func mergeEditionFeatures(parentDesc protoreflect.Descriptor, child *descriptorpb.FeatureSet) filedesc.EditionFeatures {
	var parentFS filedesc.EditionFeatures
	switch p := parentDesc.(type) {
	case *filedesc.File:
		parentFS = p.L1.EditionFeatures
	case *filedesc.Message:
		parentFS = p.L1.EditionFeatures
	default:
		panic(fmt.Sprintf("unknown parent type %T", parentDesc))
	}
	if child == nil {
		return parentFS
	}
	if fp := child.FieldPresence; fp != nil {
		parentFS.IsFieldPresence = *fp == descriptorpb.FeatureSet_LEGACY_REQUIRED ||
			*fp == descriptorpb.FeatureSet_EXPLICIT
		parentFS.IsLegacyRequired = *fp == descriptorpb.FeatureSet_LEGACY_REQUIRED
	}
	if et := child.EnumType; et != nil {
		parentFS.IsOpenEnum = *et == descriptorpb.FeatureSet_OPEN
	}

	if rfe := child.RepeatedFieldEncoding; rfe != nil {
		parentFS.IsPacked = *rfe == descriptorpb.FeatureSet_PACKED
	}

	if utf8val := child.Utf8Validation; utf8val != nil {
		parentFS.IsUTF8Validated = *utf8val == descriptorpb.FeatureSet_VERIFY
	}

	if me := child.MessageEncoding; me != nil {
		parentFS.IsDelimitedEncoded = *me == descriptorpb.FeatureSet_DELIMITED
	}

	if jf := child.JsonFormat; jf != nil {
		parentFS.IsJSONCompliant = *jf == descriptorpb.FeatureSet_ALLOW
	}

	if goFeatures, ok := proto.GetExtension(child, gofeaturespb.E_Go).(*gofeaturespb.GoFeatures); ok && goFeatures != nil {
		if luje := goFeatures.LegacyUnmarshalJsonEnum; luje != nil {
			parentFS.GenerateLegacyUnmarshalJSON = *luje
		}
	}

	return parentFS
}

// initFileDescFromFeatureSet initializes editions related fields in fd based
// on fs. If fs is nil it is assumed to be an empty featureset and all fields
// will be initialized with the appropriate default. fd.L1.Edition must be set
// before calling this function.
func initFileDescFromFeatureSet(fd *filedesc.File, fs *descriptorpb.FeatureSet) {
	dfs := getFeatureSetFor(fd.L1.Edition)
	// initialize the featureset with the defaults
	fd.L1.EditionFeatures = mergeEditionFeatures(fd, dfs)
	// overwrite any options explicitly specified
	fd.L1.EditionFeatures = mergeEditionFeatures(fd, fs)
}
