// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package protosource

import (
	"testing"
)

import (
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"google.golang.org/protobuf/proto"

	"google.golang.org/protobuf/reflect/protodesc"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"

	"google.golang.org/protobuf/types/descriptorpb"
	"google.golang.org/protobuf/types/dynamicpb"
)

func TestOptionExtensionLocation(t *testing.T) {
	t.Parallel()
	locations := []*descriptorpb.SourceCodeInfo_Location{
		{
			Path:            []int32{1, 2, 3, 4, 5, 1099, 100, 101, 102},
			Span:            []int32{99, 100, 101},
			LeadingComments: proto.String("inside custom option 1099 (100)"),
		},
		{
			Path:            []int32{1, 2, 3, 4, 5, 1099, 100, 102, 103},
			Span:            []int32{99, 100, 102},
			LeadingComments: proto.String("inside custom option 1099 (100 again)"),
		},
		{
			Path:            []int32{1, 2, 3, 4, 5, 1099, 200},
			Span:            []int32{99, 200, 201},
			LeadingComments: proto.String("inside custom option 1099 (200)"),
		},
		{
			Path:            []int32{1, 2, 3, 4, 5, 1089},
			Span:            []int32{89, 1, 2},
			LeadingComments: proto.String("custom option 1089"),
		},
		{
			Path:            []int32{1, 2, 3, 4, 5, 1079},
			Span:            []int32{79, 1, 2},
			LeadingComments: proto.String("custom option 1079"),
		},
		{
			Path:            []int32{1, 2, 3, 4, 5, 1079},
			Span:            []int32{79, 11, 12},
			LeadingComments: proto.String("custom option 1079 (again)"),
		},
		{
			Path:            []int32{1, 2, 3, 4, 5},
			Span:            []int32{5, 1, 2},
			LeadingComments: proto.String("options"),
		},
	}
	locationStore := newLocationStore(locations)
	descriptor := newOptionExtensionDescriptor(&descriptorpb.MessageOptions{}, []int32{1, 2, 3, 4, 5}, locationStore)
	customOption1079 := makeCustomOption(t, 1079)
	customOption1089 := makeCustomOption(t, 1089)
	customOption1099 := makeCustomOption(t, 1099)
	customOption1109 := makeCustomOption(t, 1109)

	assert.Nil(t, descriptor.OptionExtensionLocation(customOption1109))
	assert.Nil(t, descriptor.OptionExtensionLocation(customOption1099, 100, 103))
	assert.Nil(t, descriptor.OptionExtensionLocation(customOption1099, 300))

	loc := descriptor.OptionExtensionLocation(customOption1099)
	checkLocation(t, loc, locations[0])
	loc = descriptor.OptionExtensionLocation(customOption1099, 100)
	checkLocation(t, loc, locations[0])
	loc = descriptor.OptionExtensionLocation(customOption1099, 100, 101)
	checkLocation(t, loc, locations[0])
	loc = descriptor.OptionExtensionLocation(customOption1099, 100, 101, 102)
	checkLocation(t, loc, locations[0])
	loc = descriptor.OptionExtensionLocation(customOption1099, 100, 101, 102, 103)
	checkLocation(t, loc, locations[0])

	loc = descriptor.OptionExtensionLocation(customOption1099, 100, 102)
	checkLocation(t, loc, locations[1])
	loc = descriptor.OptionExtensionLocation(customOption1099, 100, 102, 103)
	checkLocation(t, loc, locations[1])
	loc = descriptor.OptionExtensionLocation(customOption1099, 100, 102, 103, 1, 2, 3, 4)
	checkLocation(t, loc, locations[1])

	loc = descriptor.OptionExtensionLocation(customOption1099, 200)
	checkLocation(t, loc, locations[2])
	loc = descriptor.OptionExtensionLocation(customOption1099, 200, 0)
	checkLocation(t, loc, locations[2])

	loc = descriptor.OptionExtensionLocation(customOption1089)
	checkLocation(t, loc, locations[3])
	loc = descriptor.OptionExtensionLocation(customOption1089, 10)
	checkLocation(t, loc, locations[3])

	loc = descriptor.OptionExtensionLocation(customOption1079)
	checkLocation(t, loc, locations[4])
	loc = descriptor.OptionExtensionLocation(customOption1079, 1, 2, 3)
	checkLocation(t, loc, locations[4])
}

func checkLocation(t *testing.T, loc Location, sourceCodeInfoLoc *descriptorpb.SourceCodeInfo_Location) {
	t.Helper()
	assert.Equal(t, sourceCodeInfoLoc.GetLeadingComments(), loc.LeadingComments())
	span := []int32{int32(loc.StartLine() - 1), int32(loc.StartColumn() - 1)}
	if loc.EndLine() != loc.StartLine() {
		span = append(span, int32(loc.EndLine()-1))
	}
	span = append(span, int32(loc.EndColumn()-1))
	assert.Equal(t, sourceCodeInfoLoc.Span, span)
}

func makeCustomOption(t *testing.T, tag int32) protoreflect.ExtensionType {
	t.Helper()
	fileDescriptorProto := &descriptorpb.FileDescriptorProto{
		Name:       proto.String("test.proto"),
		Syntax:     proto.String("proto2"),
		Dependency: []string{"google/protobuf/descriptor.proto"},
		Extension: []*descriptorpb.FieldDescriptorProto{
			{
				Name:     proto.String("test"),
				Number:   proto.Int32(tag),
				Type:     descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
				Label:    descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
				Extendee: proto.String(".google.protobuf.MessageOptions"),
			},
		},
	}
	fileDescriptor, err := protodesc.NewFile(fileDescriptorProto, protoregistry.GlobalFiles)
	require.NoError(t, err)
	return dynamicpb.NewExtensionType(fileDescriptor.Extensions().Get(0))
}
