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

import (
	"context"
	"fmt"
	"net/url"
	"testing"
)

import (
	hessian "github.com/apache/dubbo-go-hessian2"

	"github.com/golang/mock/gomock"

	perrors "github.com/pkg/errors"

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

import (
	"dubbo.apache.org/dubbo-go/v3/common"
	"dubbo.apache.org/dubbo-go/v3/common/constant"
	"dubbo.apache.org/dubbo-go/v3/filter/generic/generalizer"
	"dubbo.apache.org/dubbo-go/v3/protocol"
	"dubbo.apache.org/dubbo-go/v3/protocol/invocation"
	"dubbo.apache.org/dubbo-go/v3/protocol/mock"
)

type MockHelloService struct{}

func (s *MockHelloService) Hello(who string) (string, error) {
	return fmt.Sprintf("hello, %s", who), nil
}

func (s *MockHelloService) JavaClassName() string {
	return "org.apache.dubbo.hello"
}

func (s *MockHelloService) Reference() string {
	return "org.apache.dubbo.test"
}

func (s *MockHelloService) HelloPB(req *generalizer.RequestType) (*generalizer.ResponseType, error) {
	if req.GetId() == 1 {
		return &generalizer.ResponseType{
			Code:    200,
			Id:      1,
			Name:    "xavierniu",
			Message: "Nice to meet you",
		}, nil
	}
	return nil, perrors.Errorf("people not found")
}

func TestServiceFilter_Invoke(t *testing.T) {
	filter := &ServiceFilter{}

	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	mockInvoker := mock.NewMockInvoker(ctrl)

	// methodName is not "$invoke"
	invocation1 := invocation.NewRPCInvocation("test", nil, nil)
	mockInvoker.EXPECT().Invoke(gomock.Eq(invocation1))
	_ = filter.Invoke(context.Background(), mockInvoker, invocation1)
	// arguments are nil
	invocation2 := invocation.NewRPCInvocation(constant.GENERIC, nil, nil)
	mockInvoker.EXPECT().Invoke(gomock.Eq(invocation2))
	_ = filter.Invoke(context.Background(), mockInvoker, invocation2)
	// the number of arguments is not 3
	invocation3 := invocation.NewRPCInvocation(constant.GENERIC, []interface{}{"hello"}, nil)
	mockInvoker.EXPECT().Invoke(gomock.Eq(invocation3))
	_ = filter.Invoke(context.Background(), mockInvoker, invocation3)

	// hello service
	service := &MockHelloService{}
	// invoke URL
	ivkUrl := common.NewURLWithOptions(
		common.WithProtocol("test"),
		common.WithParams(url.Values{}),
		common.WithParamsValue(constant.INTERFACE_KEY, service.Reference()),
		common.WithParamsValue(constant.GENERIC_KEY, constant.GenericSerializationDefault))
	// registry RPC service
	_, err := common.ServiceMap.Register(ivkUrl.GetParam(constant.INTERFACE_KEY, ""),
		ivkUrl.Protocol,
		"",
		"",
		service)
	assert.Nil(t, err)

	// mock
	mockInvoker.EXPECT().GetUrl().Return(ivkUrl).Times(3)

	// invoke a method without errors using default generalization
	invocation4 := invocation.NewRPCInvocation(constant.GENERIC,
		[]interface{}{
			"Hello",
			[]string{"java.lang.String"},
			[]hessian.Object{"world"},
		}, map[string]interface{}{
			constant.GENERIC_KEY: "true",
		})
	// invoke a non-existed method
	invocation5 := invocation.NewRPCInvocation(constant.GENERIC,
		[]interface{}{
			"hello11",
			[]string{"java.lang.String"},
			[]hessian.Object{"world"},
		}, map[string]interface{}{
			constant.GENERIC_KEY: "true",
		})
	// invoke a method with incorrect arguments
	invocation6 := invocation.NewRPCInvocation(constant.GENERIC,
		[]interface{}{
			"Hello",
			[]string{"java.lang.String", "java.lang.String"},
			[]hessian.Object{"world", "haha"},
		}, map[string]interface{}{
			constant.GENERIC_KEY: "true",
		})
	// invoke a method without errors using protobuf-json generalization
	//invocation7 := invocation.NewRPCInvocation(constant.GENERIC,
	//	[]interface{}{
	//		"HelloPB",
	//		[]string{},
	//		[]hessian.Object{"{\"id\":1}"},
	//	}, map[string]interface{}{
	//		constant.GENERIC_KEY: constant.GenericSerializationProtobuf,
	//	})

	mockInvoker.EXPECT().Invoke(gomock.All(
		gomock.Not(invocation1),
		gomock.Not(invocation2),
		gomock.Not(invocation3),
	)).DoAndReturn(
		func(invocation protocol.Invocation) protocol.Result {
			switch invocation.MethodName() {
			case "Hello":
				who := invocation.Arguments()[0].(string)
				result, _ := service.Hello(who)
				return &protocol.RPCResult{
					Rest: result,
				}
			case "HelloPB":
				req := invocation.Arguments()[0].(*generalizer.RequestType)
				result, _ := service.HelloPB(req)
				return &protocol.RPCResult{
					Rest: result,
				}
			default:
				panic("this branch shouldn't be reached")
			}
		}).AnyTimes()

	result := filter.Invoke(context.Background(), mockInvoker, invocation4)
	assert.Nil(t, result.Error())
	assert.Equal(t, "hello, world", result.Result())

	result = filter.Invoke(context.Background(), mockInvoker, invocation5)
	assert.Equal(t,
		fmt.Sprintf("\"hello11\" method is not found, service key: %s", ivkUrl.ServiceKey()),
		fmt.Sprintf("%v", result.Error().(error)))

	result = filter.Invoke(context.Background(), mockInvoker, invocation6)
	assert.Equal(t,
		"the number of args(=2) is not matched with \"Hello\" method",
		fmt.Sprintf("%v", result.Error().(error)))

	//result = filter.Invoke(context.Background(), mockInvoker, invocation7)
	//assert.Equal(t, int64(200), result.Result().(*generalizer.ResponseType).GetCode())
	//assert.Equal(t, int64(1), result.Result().(*generalizer.ResponseType).GetId())
	//assert.Equal(t, "xavierniu", result.Result().(*generalizer.ResponseType).GetName())
	//assert.Equal(t, "Nice to meet you", result.Result().(*generalizer.ResponseType).GetMessage())

}

func TestServiceFilter_OnResponse(t *testing.T) {
	filter := &ServiceFilter{}

	// invoke a method without errors
	invocation1 := invocation.NewRPCInvocation(constant.GENERIC,
		[]interface{}{
			"hello",
			[]interface{}{"java.lang.String"},
			[]interface{}{"world"},
		}, map[string]interface{}{
			constant.GENERIC_KEY: "true",
		})

	rpcResult := &protocol.RPCResult{
		Rest: "result",
	}

	result := filter.OnResponse(context.Background(), rpcResult, nil, invocation1)
	assert.Equal(t, "result", result.Result())
}
