package protoparse

import (
	"bytes"
	"strings"

	"github.com/golang/protobuf/proto"
	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"

	"github.com/jhump/protoreflect/desc/internal"
)

func (r *parseResult) generateSourceCodeInfo() *dpb.SourceCodeInfo {
	if r.nodes == nil {
		// skip files that do not have AST info (these will be files
		// that came from well-known descriptors, instead of from source)
		return nil
	}

	sci := sourceCodeInfo{commentsUsed: map[*comment]struct{}{}}
	path := make([]int32, 0, 10)

	fn := r.getFileNode(r.fd).(*fileNode)
	sci.newLocWithoutComments(fn, nil)

	if fn.syntax != nil {
		sci.newLoc(fn.syntax, append(path, internal.File_syntaxTag))
	}

	var depIndex, optIndex, msgIndex, enumIndex, extendIndex, svcIndex int32

	for _, child := range fn.decls {
		switch {
		case child.imp != nil:
			sci.newLoc(child.imp, append(path, internal.File_dependencyTag, int32(depIndex)))
			depIndex++
		case child.pkg != nil:
			sci.newLoc(child.pkg, append(path, internal.File_packageTag))
		case child.option != nil:
			r.generateSourceCodeInfoForOption(&sci, child.option, false, &optIndex, append(path, internal.File_optionsTag))
		case child.message != nil:
			r.generateSourceCodeInfoForMessage(&sci, child.message, nil, append(path, internal.File_messagesTag, msgIndex))
			msgIndex++
		case child.enum != nil:
			r.generateSourceCodeInfoForEnum(&sci, child.enum, append(path, internal.File_enumsTag, enumIndex))
			enumIndex++
		case child.extend != nil:
			r.generateSourceCodeInfoForExtensions(&sci, child.extend, &extendIndex, &msgIndex, append(path, internal.File_extensionsTag), append(dup(path), internal.File_messagesTag))
		case child.service != nil:
			r.generateSourceCodeInfoForService(&sci, child.service, append(path, internal.File_servicesTag, svcIndex))
			svcIndex++
		}
	}

	return &dpb.SourceCodeInfo{Location: sci.locs}
}

func (r *parseResult) generateSourceCodeInfoForOption(sci *sourceCodeInfo, n *optionNode, compact bool, uninterpIndex *int32, path []int32) {
	if !compact {
		sci.newLocWithoutComments(n, path)
	}
	subPath := r.interpretedOptions[n]
	if len(subPath) > 0 {
		p := path
		if subPath[0] == -1 {
			// used by "default" and "json_name" field pseudo-options
			// to attribute path to parent element (since those are
			// stored directly on the descriptor, not its options)
			p = make([]int32, len(path)-1)
			copy(p, path)
			subPath = subPath[1:]
		}
		sci.newLoc(n, append(p, subPath...))
		return
	}

	// it's an uninterpreted option
	optPath := append(path, internal.UninterpretedOptionsTag, *uninterpIndex)
	*uninterpIndex++
	sci.newLoc(n, optPath)
	var valTag int32
	switch n.val.(type) {
	case *compoundIdentNode:
		valTag = internal.Uninterpreted_identTag
	case *intLiteralNode:
		valTag = internal.Uninterpreted_posIntTag
	case *compoundIntNode:
		valTag = internal.Uninterpreted_negIntTag
	case *compoundFloatNode:
		valTag = internal.Uninterpreted_doubleTag
	case *compoundStringNode:
		valTag = internal.Uninterpreted_stringTag
	case *aggregateLiteralNode:
		valTag = internal.Uninterpreted_aggregateTag
	}
	if valTag != 0 {
		sci.newLoc(n.val, append(optPath, valTag))
	}
	for j, nn := range n.name.parts {
		optNmPath := append(optPath, internal.Uninterpreted_nameTag, int32(j))
		sci.newLoc(nn, optNmPath)
		sci.newLoc(nn.text, append(optNmPath, internal.UninterpretedName_nameTag))
	}
}

func (r *parseResult) generateSourceCodeInfoForMessage(sci *sourceCodeInfo, n msgDecl, fieldPath []int32, path []int32) {
	sci.newLoc(n, path)

	var decls []*messageElement
	switch n := n.(type) {
	case *messageNode:
		decls = n.decls
	case *groupNode:
		decls = n.decls
	case *mapFieldNode:
		// map entry so nothing else to do
		return
	}

	sci.newLoc(n.messageName(), append(path, internal.Message_nameTag))
	// matching protoc, which emits the corresponding field type name (for group fields)
	// right after the source location for the group message name
	if fieldPath != nil {
		sci.newLoc(n.messageName(), append(fieldPath, internal.Field_typeNameTag))
	}

	var optIndex, fieldIndex, oneOfIndex, extendIndex, nestedMsgIndex int32
	var nestedEnumIndex, extRangeIndex, reservedRangeIndex, reservedNameIndex int32
	for _, child := range decls {
		switch {
		case child.option != nil:
			r.generateSourceCodeInfoForOption(sci, child.option, false, &optIndex, append(path, internal.Message_optionsTag))
		case child.field != nil:
			r.generateSourceCodeInfoForField(sci, child.field, append(path, internal.Message_fieldsTag, fieldIndex))
			fieldIndex++
		case child.group != nil:
			fldPath := append(path, internal.Message_fieldsTag, fieldIndex)
			r.generateSourceCodeInfoForField(sci, child.group, fldPath)
			fieldIndex++
			r.generateSourceCodeInfoForMessage(sci, child.group, fldPath, append(dup(path), internal.Message_nestedMessagesTag, nestedMsgIndex))
			nestedMsgIndex++
		case child.mapField != nil:
			r.generateSourceCodeInfoForField(sci, child.mapField, append(path, internal.Message_fieldsTag, fieldIndex))
			fieldIndex++
		case child.oneOf != nil:
			r.generateSourceCodeInfoForOneOf(sci, child.oneOf, &fieldIndex, &nestedMsgIndex, append(path, internal.Message_fieldsTag), append(dup(path), internal.Message_nestedMessagesTag), append(dup(path), internal.Message_oneOfsTag, oneOfIndex))
			oneOfIndex++
		case child.nested != nil:
			r.generateSourceCodeInfoForMessage(sci, child.nested, nil, append(path, internal.Message_nestedMessagesTag, nestedMsgIndex))
			nestedMsgIndex++
		case child.enum != nil:
			r.generateSourceCodeInfoForEnum(sci, child.enum, append(path, internal.Message_enumsTag, nestedEnumIndex))
			nestedEnumIndex++
		case child.extend != nil:
			r.generateSourceCodeInfoForExtensions(sci, child.extend, &extendIndex, &nestedMsgIndex, append(path, internal.Message_extensionsTag), append(dup(path), internal.Message_nestedMessagesTag))
		case child.extensionRange != nil:
			r.generateSourceCodeInfoForExtensionRanges(sci, child.extensionRange, &extRangeIndex, append(path, internal.Message_extensionRangeTag))
		case child.reserved != nil:
			if len(child.reserved.names) > 0 {
				resPath := append(path, internal.Message_reservedNameTag)
				sci.newLoc(child.reserved, resPath)
				for _, rn := range child.reserved.names {
					sci.newLoc(rn, append(resPath, reservedNameIndex))
					reservedNameIndex++
				}
			}
			if len(child.reserved.ranges) > 0 {
				resPath := append(path, internal.Message_reservedRangeTag)
				sci.newLoc(child.reserved, resPath)
				for _, rr := range child.reserved.ranges {
					r.generateSourceCodeInfoForReservedRange(sci, rr, append(resPath, reservedRangeIndex))
					reservedRangeIndex++
				}
			}
		}
	}
}

func (r *parseResult) generateSourceCodeInfoForEnum(sci *sourceCodeInfo, n *enumNode, path []int32) {
	sci.newLoc(n, path)
	sci.newLoc(n.name, append(path, internal.Enum_nameTag))

	var optIndex, valIndex, reservedNameIndex, reservedRangeIndex int32
	for _, child := range n.decls {
		switch {
		case child.option != nil:
			r.generateSourceCodeInfoForOption(sci, child.option, false, &optIndex, append(path, internal.Enum_optionsTag))
		case child.value != nil:
			r.generateSourceCodeInfoForEnumValue(sci, child.value, append(path, internal.Enum_valuesTag, valIndex))
			valIndex++
		case child.reserved != nil:
			if len(child.reserved.names) > 0 {
				resPath := append(path, internal.Enum_reservedNameTag)
				sci.newLoc(child.reserved, resPath)
				for _, rn := range child.reserved.names {
					sci.newLoc(rn, append(resPath, reservedNameIndex))
					reservedNameIndex++
				}
			}
			if len(child.reserved.ranges) > 0 {
				resPath := append(path, internal.Enum_reservedRangeTag)
				sci.newLoc(child.reserved, resPath)
				for _, rr := range child.reserved.ranges {
					r.generateSourceCodeInfoForReservedRange(sci, rr, append(resPath, reservedRangeIndex))
					reservedRangeIndex++
				}
			}
		}
	}
}

func (r *parseResult) generateSourceCodeInfoForEnumValue(sci *sourceCodeInfo, n *enumValueNode, path []int32) {
	sci.newLoc(n, path)
	sci.newLoc(n.name, append(path, internal.EnumVal_nameTag))
	sci.newLoc(n.getNumber(), append(path, internal.EnumVal_numberTag))

	// enum value options
	if n.options != nil {
		optsPath := append(path, internal.EnumVal_optionsTag)
		sci.newLoc(n.options, optsPath)
		var optIndex int32
		for _, opt := range n.options.decls {
			r.generateSourceCodeInfoForOption(sci, opt, true, &optIndex, optsPath)
		}
	}
}

func (r *parseResult) generateSourceCodeInfoForReservedRange(sci *sourceCodeInfo, n *rangeNode, path []int32) {
	sci.newLoc(n, path)
	sci.newLoc(n.stNode, append(path, internal.ReservedRange_startTag))
	if n.stNode != n.enNode {
		sci.newLoc(n.enNode, append(path, internal.ReservedRange_endTag))
	}
}

func (r *parseResult) generateSourceCodeInfoForExtensions(sci *sourceCodeInfo, n *extendNode, extendIndex, msgIndex *int32, extendPath, msgPath []int32) {
	sci.newLoc(n, extendPath)
	for _, decl := range n.decls {
		switch {
		case decl.field != nil:
			r.generateSourceCodeInfoForField(sci, decl.field, append(extendPath, *extendIndex))
			*extendIndex++
		case decl.group != nil:
			fldPath := append(extendPath, *extendIndex)
			r.generateSourceCodeInfoForField(sci, decl.group, fldPath)
			*extendIndex++
			r.generateSourceCodeInfoForMessage(sci, decl.group, fldPath, append(msgPath, *msgIndex))
			*msgIndex++
		}
	}
}

func (r *parseResult) generateSourceCodeInfoForOneOf(sci *sourceCodeInfo, n *oneOfNode, fieldIndex, nestedMsgIndex *int32, fieldPath, nestedMsgPath, oneOfPath []int32) {
	sci.newLoc(n, oneOfPath)
	sci.newLoc(n.name, append(oneOfPath, internal.OneOf_nameTag))

	var optIndex int32
	for _, child := range n.decls {
		switch {
		case child.option != nil:
			r.generateSourceCodeInfoForOption(sci, child.option, false, &optIndex, append(oneOfPath, internal.OneOf_optionsTag))
		case child.field != nil:
			r.generateSourceCodeInfoForField(sci, child.field, append(fieldPath, *fieldIndex))
			*fieldIndex++
		case child.group != nil:
			fldPath := append(fieldPath, *fieldIndex)
			r.generateSourceCodeInfoForField(sci, child.group, fldPath)
			*fieldIndex++
			r.generateSourceCodeInfoForMessage(sci, child.group, fldPath, append(nestedMsgPath, *nestedMsgIndex))
			*nestedMsgIndex++
		}
	}
}

func (r *parseResult) generateSourceCodeInfoForField(sci *sourceCodeInfo, n fieldDecl, path []int32) {
	isGroup := false
	var opts *compactOptionsNode
	var extendee *extendNode
	var fieldType string
	switch n := n.(type) {
	case *fieldNode:
		opts = n.options
		extendee = n.extendee
		fieldType = n.fldType.val
	case *mapFieldNode:
		opts = n.options
	case *groupNode:
		isGroup = true
		extendee = n.extendee
	case *syntheticMapField:
		// shouldn't get here since we don't recurse into fields from a mapNode
		// in generateSourceCodeInfoForMessage... but just in case
		return
	}

	if isGroup {
		// comments will appear on group message
		sci.newLocWithoutComments(n, path)
		if extendee != nil {
			sci.newLoc(extendee.extendee, append(path, internal.Field_extendeeTag))
		}
		if n.fieldLabel() != nil {
			// no comments here either (label is first token for group, so we want
			// to leave the comments to be associated with the group message instead)
			sci.newLocWithoutComments(n.fieldLabel(), append(path, internal.Field_labelTag))
		}
		sci.newLoc(n.fieldType(), append(path, internal.Field_typeTag))
		// let the name comments be attributed to the group name
		sci.newLocWithoutComments(n.fieldName(), append(path, internal.Field_nameTag))
	} else {
		sci.newLoc(n, path)
		if extendee != nil {
			sci.newLoc(extendee.extendee, append(path, internal.Field_extendeeTag))
		}
		if n.fieldLabel() != nil {
			sci.newLoc(n.fieldLabel(), append(path, internal.Field_labelTag))
		}
		n.fieldType()
		var tag int32
		if _, isScalar := fieldTypes[fieldType]; isScalar {
			tag = internal.Field_typeTag
		} else {
			// this is a message or an enum, so attribute type location
			// to the type name field
			tag = internal.Field_typeNameTag
		}
		sci.newLoc(n.fieldType(), append(path, tag))
		sci.newLoc(n.fieldName(), append(path, internal.Field_nameTag))
	}
	sci.newLoc(n.fieldTag(), append(path, internal.Field_numberTag))

	if opts != nil {
		optsPath := append(path, internal.Field_optionsTag)
		sci.newLoc(opts, optsPath)
		var optIndex int32
		for _, opt := range opts.decls {
			r.generateSourceCodeInfoForOption(sci, opt, true, &optIndex, optsPath)
		}
	}
}

func (r *parseResult) generateSourceCodeInfoForExtensionRanges(sci *sourceCodeInfo, n *extensionRangeNode, extRangeIndex *int32, path []int32) {
	sci.newLoc(n, path)
	for _, child := range n.ranges {
		path := append(path, *extRangeIndex)
		*extRangeIndex++
		sci.newLoc(child, path)
		sci.newLoc(child.stNode, append(path, internal.ExtensionRange_startTag))
		if child.stNode != child.enNode {
			sci.newLoc(child.enNode, append(path, internal.ExtensionRange_endTag))
		}
		if n.options != nil {
			optsPath := append(path, internal.ExtensionRange_optionsTag)
			sci.newLoc(n.options, optsPath)
			var optIndex int32
			for _, opt := range n.options.decls {
				r.generateSourceCodeInfoForOption(sci, opt, true, &optIndex, optsPath)
			}
		}
	}
}

func (r *parseResult) generateSourceCodeInfoForService(sci *sourceCodeInfo, n *serviceNode, path []int32) {
	sci.newLoc(n, path)
	sci.newLoc(n.name, append(path, internal.Service_nameTag))
	var optIndex, rpcIndex int32
	for _, child := range n.decls {
		switch {
		case child.option != nil:
			r.generateSourceCodeInfoForOption(sci, child.option, false, &optIndex, append(path, internal.Service_optionsTag))
		case child.rpc != nil:
			r.generateSourceCodeInfoForMethod(sci, child.rpc, append(path, internal.Service_methodsTag, rpcIndex))
			rpcIndex++
		}
	}
}

func (r *parseResult) generateSourceCodeInfoForMethod(sci *sourceCodeInfo, n *methodNode, path []int32) {
	sci.newLoc(n, path)
	sci.newLoc(n.name, append(path, internal.Method_nameTag))
	if n.input.streamKeyword != nil {
		sci.newLoc(n.input.streamKeyword, append(path, internal.Method_inputStreamTag))
	}
	sci.newLoc(n.input.msgType, append(path, internal.Method_inputTag))
	if n.output.streamKeyword != nil {
		sci.newLoc(n.output.streamKeyword, append(path, internal.Method_outputStreamTag))
	}
	sci.newLoc(n.output.msgType, append(path, internal.Method_outputTag))

	optsPath := append(path, internal.Method_optionsTag)
	var optIndex int32
	for _, opt := range n.options {
		r.generateSourceCodeInfoForOption(sci, opt, false, &optIndex, optsPath)
	}
}

type sourceCodeInfo struct {
	locs         []*dpb.SourceCodeInfo_Location
	commentsUsed map[*comment]struct{}
}

func (sci *sourceCodeInfo) newLocWithoutComments(n node, path []int32) {
	dup := make([]int32, len(path))
	copy(dup, path)
	sci.locs = append(sci.locs, &dpb.SourceCodeInfo_Location{
		Path: dup,
		Span: makeSpan(n.start(), n.end()),
	})
}

func (sci *sourceCodeInfo) newLoc(n node, path []int32) {
	leadingComments := n.leadingComments()
	trailingComments := n.trailingComments()
	if sci.commentUsed(leadingComments) {
		leadingComments = nil
	}
	if sci.commentUsed(trailingComments) {
		trailingComments = nil
	}
	detached := groupComments(leadingComments)
	var trail *string
	if str, ok := combineComments(trailingComments); ok {
		trail = proto.String(str)
	}
	var lead *string
	if len(leadingComments) > 0 && leadingComments[len(leadingComments)-1].end.Line >= n.start().Line-1 {
		lead = proto.String(detached[len(detached)-1])
		detached = detached[:len(detached)-1]
	}
	dup := make([]int32, len(path))
	copy(dup, path)
	sci.locs = append(sci.locs, &dpb.SourceCodeInfo_Location{
		LeadingDetachedComments: detached,
		LeadingComments:         lead,
		TrailingComments:        trail,
		Path:                    dup,
		Span:                    makeSpan(n.start(), n.end()),
	})
}

func makeSpan(start, end *SourcePos) []int32 {
	if start.Line == end.Line {
		return []int32{int32(start.Line) - 1, int32(start.Col) - 1, int32(end.Col) - 1}
	}
	return []int32{int32(start.Line) - 1, int32(start.Col) - 1, int32(end.Line) - 1, int32(end.Col) - 1}
}

func (sci *sourceCodeInfo) commentUsed(c []comment) bool {
	if len(c) == 0 {
		return false
	}
	if _, ok := sci.commentsUsed[&c[0]]; ok {
		return true
	}

	sci.commentsUsed[&c[0]] = struct{}{}
	return false
}

func groupComments(comments []comment) []string {
	if len(comments) == 0 {
		return nil
	}

	var groups []string
	singleLineStyle := comments[0].text[:2] == "//"
	line := comments[0].end.Line
	start := 0
	for i := 1; i < len(comments); i++ {
		c := comments[i]
		prevSingleLine := singleLineStyle
		singleLineStyle = strings.HasPrefix(comments[i].text, "//")
		if !singleLineStyle || prevSingleLine != singleLineStyle || c.start.Line > line+1 {
			// new group!
			if str, ok := combineComments(comments[start:i]); ok {
				groups = append(groups, str)
			}
			start = i
		}
		line = c.end.Line
	}
	// don't forget last group
	if str, ok := combineComments(comments[start:]); ok {
		groups = append(groups, str)
	}
	return groups
}

func combineComments(comments []comment) (string, bool) {
	if len(comments) == 0 {
		return "", false
	}
	var buf bytes.Buffer
	for _, c := range comments {
		if c.text[:2] == "//" {
			buf.WriteString(c.text[2:])
		} else {
			lines := strings.Split(c.text[2:len(c.text)-2], "\n")
			first := true
			for _, l := range lines {
				if first {
					first = false
				} else {
					buf.WriteByte('\n')
				}

				// strip a prefix of whitespace followed by '*'
				j := 0
				for j < len(l) {
					if l[j] != ' ' && l[j] != '\t' {
						break
					}
					j++
				}
				if j == len(l) {
					l = ""
				} else if l[j] == '*' {
					l = l[j+1:]
				} else if j > 0 {
					l = " " + l[j:]
				}

				buf.WriteString(l)
			}
		}
	}
	return buf.String(), true
}

func dup(p []int32) []int32 {
	return append(([]int32)(nil), p...)
}
