// Copyright 2016 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 ptypes

import (
	"fmt"
	"strings"

	"github.com/golang/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"

	anypb "github.com/golang/protobuf/ptypes/any"
)

const urlPrefix = "type.googleapis.com/"

// AnyMessageName returns the message name contained in an anypb.Any message.
// Most type assertions should use the Is function instead.
//
// Deprecated: Call the any.MessageName method instead.
func AnyMessageName(any *anypb.Any) (string, error) {
	name, err := anyMessageName(any)
	return string(name), err
}
func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) {
	if any == nil {
		return "", fmt.Errorf("message is nil")
	}
	name := protoreflect.FullName(any.TypeUrl)
	if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 {
		name = name[i+len("/"):]
	}
	if !name.IsValid() {
		return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl)
	}
	return name, nil
}

// MarshalAny marshals the given message m into an anypb.Any message.
//
// Deprecated: Call the anypb.New function instead.
func MarshalAny(m proto.Message) (*anypb.Any, error) {
	switch dm := m.(type) {
	case DynamicAny:
		m = dm.Message
	case *DynamicAny:
		if dm == nil {
			return nil, proto.ErrNil
		}
		m = dm.Message
	}
	b, err := proto.Marshal(m)
	if err != nil {
		return nil, err
	}
	return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil
}

// Empty returns a new message of the type specified in an anypb.Any message.
// It returns protoregistry.NotFound if the corresponding message type could not
// be resolved in the global registry.
//
// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead
// to resolve the message name and create a new instance of it.
func Empty(any *anypb.Any) (proto.Message, error) {
	name, err := anyMessageName(any)
	if err != nil {
		return nil, err
	}
	mt, err := protoregistry.GlobalTypes.FindMessageByName(name)
	if err != nil {
		return nil, err
	}
	return proto.MessageV1(mt.New().Interface()), nil
}

// UnmarshalAny unmarshals the encoded value contained in the anypb.Any message
// into the provided message m. It returns an error if the target message
// does not match the type in the Any message or if an unmarshal error occurs.
//
// The target message m may be a *DynamicAny message. If the underlying message
// type could not be resolved, then this returns protoregistry.NotFound.
//
// Deprecated: Call the any.UnmarshalTo method instead.
func UnmarshalAny(any *anypb.Any, m proto.Message) error {
	if dm, ok := m.(*DynamicAny); ok {
		if dm.Message == nil {
			var err error
			dm.Message, err = Empty(any)
			if err != nil {
				return err
			}
		}
		m = dm.Message
	}

	anyName, err := AnyMessageName(any)
	if err != nil {
		return err
	}
	msgName := proto.MessageName(m)
	if anyName != msgName {
		return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName)
	}
	return proto.Unmarshal(any.Value, m)
}

// Is reports whether the Any message contains a message of the specified type.
//
// Deprecated: Call the any.MessageIs method instead.
func Is(any *anypb.Any, m proto.Message) bool {
	if any == nil || m == nil {
		return false
	}
	name := proto.MessageName(m)
	if !strings.HasSuffix(any.TypeUrl, name) {
		return false
	}
	return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/'
}

// DynamicAny is a value that can be passed to UnmarshalAny to automatically
// allocate a proto.Message for the type specified in an anypb.Any message.
// The allocated message is stored in the embedded proto.Message.
//
// Example:
//   var x ptypes.DynamicAny
//   if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
//   fmt.Printf("unmarshaled message: %v", x.Message)
//
// Deprecated: Use the any.UnmarshalNew method instead to unmarshal
// the any message contents into a new instance of the underlying message.
type DynamicAny struct{ proto.Message }

func (m DynamicAny) String() string {
	if m.Message == nil {
		return "<nil>"
	}
	return m.Message.String()
}
func (m DynamicAny) Reset() {
	if m.Message == nil {
		return
	}
	m.Message.Reset()
}
func (m DynamicAny) ProtoMessage() {
	return
}
func (m DynamicAny) ProtoReflect() protoreflect.Message {
	if m.Message == nil {
		return nil
	}
	return dynamicAny{proto.MessageReflect(m.Message)}
}

type dynamicAny struct{ protoreflect.Message }

func (m dynamicAny) Type() protoreflect.MessageType {
	return dynamicAnyType{m.Message.Type()}
}
func (m dynamicAny) New() protoreflect.Message {
	return dynamicAnyType{m.Message.Type()}.New()
}
func (m dynamicAny) Interface() protoreflect.ProtoMessage {
	return DynamicAny{proto.MessageV1(m.Message.Interface())}
}

type dynamicAnyType struct{ protoreflect.MessageType }

func (t dynamicAnyType) New() protoreflect.Message {
	return dynamicAny{t.MessageType.New()}
}
func (t dynamicAnyType) Zero() protoreflect.Message {
	return dynamicAny{t.MessageType.Zero()}
}
