// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package descriptor

import (
	"strings"
)

func (msg *DescriptorProto) GetMapFields() (*FieldDescriptorProto, *FieldDescriptorProto) {
	if !msg.GetOptions().GetMapEntry() {
		return nil, nil
	}
	return msg.GetField()[0], msg.GetField()[1]
}

func dotToUnderscore(r rune) rune {
	if r == '.' {
		return '_'
	}
	return r
}

func (field *FieldDescriptorProto) WireType() (wire int) {
	switch *field.Type {
	case FieldDescriptorProto_TYPE_DOUBLE:
		return 1
	case FieldDescriptorProto_TYPE_FLOAT:
		return 5
	case FieldDescriptorProto_TYPE_INT64:
		return 0
	case FieldDescriptorProto_TYPE_UINT64:
		return 0
	case FieldDescriptorProto_TYPE_INT32:
		return 0
	case FieldDescriptorProto_TYPE_UINT32:
		return 0
	case FieldDescriptorProto_TYPE_FIXED64:
		return 1
	case FieldDescriptorProto_TYPE_FIXED32:
		return 5
	case FieldDescriptorProto_TYPE_BOOL:
		return 0
	case FieldDescriptorProto_TYPE_STRING:
		return 2
	case FieldDescriptorProto_TYPE_GROUP:
		return 2
	case FieldDescriptorProto_TYPE_MESSAGE:
		return 2
	case FieldDescriptorProto_TYPE_BYTES:
		return 2
	case FieldDescriptorProto_TYPE_ENUM:
		return 0
	case FieldDescriptorProto_TYPE_SFIXED32:
		return 5
	case FieldDescriptorProto_TYPE_SFIXED64:
		return 1
	case FieldDescriptorProto_TYPE_SINT32:
		return 0
	case FieldDescriptorProto_TYPE_SINT64:
		return 0
	}
	panic("unreachable")
}

func (field *FieldDescriptorProto) GetKeyUint64() (x uint64) {
	packed := field.IsPacked()
	wireType := field.WireType()
	fieldNumber := field.GetNumber()
	if packed {
		wireType = 2
	}
	x = uint64(uint32(fieldNumber)<<3 | uint32(wireType))
	return x
}

func (field *FieldDescriptorProto) GetKey3Uint64() (x uint64) {
	packed := field.IsPacked3()
	wireType := field.WireType()
	fieldNumber := field.GetNumber()
	if packed {
		wireType = 2
	}
	x = uint64(uint32(fieldNumber)<<3 | uint32(wireType))
	return x
}

func (field *FieldDescriptorProto) GetKey() []byte {
	x := field.GetKeyUint64()
	i := 0
	keybuf := make([]byte, 0)
	for i = 0; x > 127; i++ {
		keybuf = append(keybuf, 0x80|uint8(x&0x7F))
		x >>= 7
	}
	keybuf = append(keybuf, uint8(x))
	return keybuf
}

func (field *FieldDescriptorProto) GetKey3() []byte {
	x := field.GetKey3Uint64()
	i := 0
	keybuf := make([]byte, 0)
	for i = 0; x > 127; i++ {
		keybuf = append(keybuf, 0x80|uint8(x&0x7F))
		x >>= 7
	}
	keybuf = append(keybuf, uint8(x))
	return keybuf
}

func (desc *FileDescriptorSet) GetField(packageName, messageName, fieldName string) *FieldDescriptorProto {
	msg := desc.GetMessage(packageName, messageName)
	if msg == nil {
		return nil
	}
	for _, field := range msg.GetField() {
		if field.GetName() == fieldName {
			return field
		}
	}
	return nil
}

func (file *FileDescriptorProto) GetMessage(typeName string) *DescriptorProto {
	for _, msg := range file.GetMessageType() {
		if msg.GetName() == typeName {
			return msg
		}
		nes := file.GetNestedMessage(msg, strings.TrimPrefix(typeName, msg.GetName()+"."))
		if nes != nil {
			return nes
		}
	}
	return nil
}

func (file *FileDescriptorProto) GetNestedMessage(msg *DescriptorProto, typeName string) *DescriptorProto {
	for _, nes := range msg.GetNestedType() {
		if nes.GetName() == typeName {
			return nes
		}
		res := file.GetNestedMessage(nes, strings.TrimPrefix(typeName, nes.GetName()+"."))
		if res != nil {
			return res
		}
	}
	return nil
}

func (desc *FileDescriptorSet) GetMessage(packageName string, typeName string) *DescriptorProto {
	for _, file := range desc.GetFile() {
		if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) {
			continue
		}
		for _, msg := range file.GetMessageType() {
			if msg.GetName() == typeName {
				return msg
			}
		}
		for _, msg := range file.GetMessageType() {
			for _, nes := range msg.GetNestedType() {
				if nes.GetName() == typeName {
					return nes
				}
				if msg.GetName()+"."+nes.GetName() == typeName {
					return nes
				}
			}
		}
	}
	return nil
}

func (desc *FileDescriptorSet) IsProto3(packageName string, typeName string) bool {
	for _, file := range desc.GetFile() {
		if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) {
			continue
		}
		for _, msg := range file.GetMessageType() {
			if msg.GetName() == typeName {
				return file.GetSyntax() == "proto3"
			}
		}
		for _, msg := range file.GetMessageType() {
			for _, nes := range msg.GetNestedType() {
				if nes.GetName() == typeName {
					return file.GetSyntax() == "proto3"
				}
				if msg.GetName()+"."+nes.GetName() == typeName {
					return file.GetSyntax() == "proto3"
				}
			}
		}
	}
	return false
}

func (msg *DescriptorProto) IsExtendable() bool {
	return len(msg.GetExtensionRange()) > 0
}

func (desc *FileDescriptorSet) FindExtension(packageName string, typeName string, fieldName string) (extPackageName string, field *FieldDescriptorProto) {
	parent := desc.GetMessage(packageName, typeName)
	if parent == nil {
		return "", nil
	}
	if !parent.IsExtendable() {
		return "", nil
	}
	extendee := "." + packageName + "." + typeName
	for _, file := range desc.GetFile() {
		for _, ext := range file.GetExtension() {
			if strings.Map(dotToUnderscore, file.GetPackage()) == strings.Map(dotToUnderscore, packageName) {
				if !(ext.GetExtendee() == typeName || ext.GetExtendee() == extendee) {
					continue
				}
			} else {
				if ext.GetExtendee() != extendee {
					continue
				}
			}
			if ext.GetName() == fieldName {
				return file.GetPackage(), ext
			}
		}
	}
	return "", nil
}

func (desc *FileDescriptorSet) FindExtensionByFieldNumber(packageName string, typeName string, fieldNum int32) (extPackageName string, field *FieldDescriptorProto) {
	parent := desc.GetMessage(packageName, typeName)
	if parent == nil {
		return "", nil
	}
	if !parent.IsExtendable() {
		return "", nil
	}
	extendee := "." + packageName + "." + typeName
	for _, file := range desc.GetFile() {
		for _, ext := range file.GetExtension() {
			if strings.Map(dotToUnderscore, file.GetPackage()) == strings.Map(dotToUnderscore, packageName) {
				if !(ext.GetExtendee() == typeName || ext.GetExtendee() == extendee) {
					continue
				}
			} else {
				if ext.GetExtendee() != extendee {
					continue
				}
			}
			if ext.GetNumber() == fieldNum {
				return file.GetPackage(), ext
			}
		}
	}
	return "", nil
}

func (desc *FileDescriptorSet) FindMessage(packageName string, typeName string, fieldName string) (msgPackageName string, msgName string) {
	parent := desc.GetMessage(packageName, typeName)
	if parent == nil {
		return "", ""
	}
	field := parent.GetFieldDescriptor(fieldName)
	if field == nil {
		var extPackageName string
		extPackageName, field = desc.FindExtension(packageName, typeName, fieldName)
		if field == nil {
			return "", ""
		}
		packageName = extPackageName
	}
	typeNames := strings.Split(field.GetTypeName(), ".")
	if len(typeNames) == 1 {
		msg := desc.GetMessage(packageName, typeName)
		if msg == nil {
			return "", ""
		}
		return packageName, msg.GetName()
	}
	if len(typeNames) > 2 {
		for i := 1; i < len(typeNames)-1; i++ {
			packageName = strings.Join(typeNames[1:len(typeNames)-i], ".")
			typeName = strings.Join(typeNames[len(typeNames)-i:], ".")
			msg := desc.GetMessage(packageName, typeName)
			if msg != nil {
				typeNames := strings.Split(msg.GetName(), ".")
				if len(typeNames) == 1 {
					return packageName, msg.GetName()
				}
				return strings.Join(typeNames[1:len(typeNames)-1], "."), typeNames[len(typeNames)-1]
			}
		}
	}
	return "", ""
}

func (msg *DescriptorProto) GetFieldDescriptor(fieldName string) *FieldDescriptorProto {
	for _, field := range msg.GetField() {
		if field.GetName() == fieldName {
			return field
		}
	}
	return nil
}

func (desc *FileDescriptorSet) GetEnum(packageName string, typeName string) *EnumDescriptorProto {
	for _, file := range desc.GetFile() {
		if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) {
			continue
		}
		for _, enum := range file.GetEnumType() {
			if enum.GetName() == typeName {
				return enum
			}
		}
	}
	return nil
}

func (f *FieldDescriptorProto) IsEnum() bool {
	return *f.Type == FieldDescriptorProto_TYPE_ENUM
}

func (f *FieldDescriptorProto) IsMessage() bool {
	return *f.Type == FieldDescriptorProto_TYPE_MESSAGE
}

func (f *FieldDescriptorProto) IsBytes() bool {
	return *f.Type == FieldDescriptorProto_TYPE_BYTES
}

func (f *FieldDescriptorProto) IsRepeated() bool {
	return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REPEATED
}

func (f *FieldDescriptorProto) IsString() bool {
	return *f.Type == FieldDescriptorProto_TYPE_STRING
}

func (f *FieldDescriptorProto) IsBool() bool {
	return *f.Type == FieldDescriptorProto_TYPE_BOOL
}

func (f *FieldDescriptorProto) IsRequired() bool {
	return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REQUIRED
}

func (f *FieldDescriptorProto) IsPacked() bool {
	return f.Options != nil && f.GetOptions().GetPacked()
}

func (f *FieldDescriptorProto) IsPacked3() bool {
	if f.IsRepeated() && f.IsScalar() {
		if f.Options == nil || f.GetOptions().Packed == nil {
			return true
		}
		return f.Options != nil && f.GetOptions().GetPacked()
	}
	return false
}

func (m *DescriptorProto) HasExtension() bool {
	return len(m.ExtensionRange) > 0
}
