/*
 * 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 dubbo3

import (
	"context"
	"reflect"
	"testing"
	"time"
)

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

import (
	"dubbo.apache.org/dubbo-go/v3/common"
	"dubbo.apache.org/dubbo-go/v3/protocol/dubbo3/internal"
	"dubbo.apache.org/dubbo-go/v3/protocol/invocation"
)

const (
	mockDubbo3CommonUrl2 = "tri://127.0.0.1:20003/DubboGreeterImpl?accesslog=&anyhost=true&app.version=0.0.1&application=BDTService&async=false&bean.name=greeterImpl" +
		"&category=providers&cluster=failover&dubbo=dubbo-provider-golang-2.6.0&environment=dev&execute.limit=&execute.limit.rejected.handler=&generic=false&group=&interface=org.apache.dubbo.DubboGreeterImpl" +
		"&ip=192.168.1.106&loadbalance=random&methods.SayHello.loadbalance=random&methods.SayHello.retries=1&methods.SayHello.tps.limit.interval=&methods.SayHello.tps.limit.rate=&methods.SayHello.tps.limit.strategy=" +
		"&methods.SayHello.weight=0&module=dubbogo+say-hello+client&name=BDTService&organization=ikurento.com&owner=ZX&pid=49427&reference.filter=cshutdown&registry.role=3&remote.timestamp=1576923717&retries=" +
		"&service.filter=echo%2Ctoken%2Caccesslog%2Ctps%2Cexecute%2Cpshutdown&side=provider&timestamp=1576923740&tps.limit.interval=&tps.limit.rate=&tps.limit.rejected.handler=&tps.limit.strategy=&tps.limiter=&version=&warmup=100!"
)

func TestInvoke(t *testing.T) {
	go internal.InitDubboServer()
	time.Sleep(time.Second * 3)

	url, err := common.NewURL(mockDubbo3CommonUrl2)
	assert.Nil(t, err)

	invoker, err := NewDubboInvoker(url)

	assert.Nil(t, err)

	args := []reflect.Value{}
	args = append(args, reflect.ValueOf(&internal.HelloRequest{Name: "request name"}))
	bizReply := &internal.HelloReply{}
	invo := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("SayHello"),
		invocation.WithParameterValues(args), invocation.WithReply(bizReply))
	res := invoker.Invoke(context.Background(), invo)
	assert.Nil(t, res.Error())
	assert.NotNil(t, res.Result())
	assert.Equal(t, "Hello request name", bizReply.Message)
}
