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

import (
	"bytes"
	"context"
	"net/http"
	"regexp"
	"testing"
)

import (
	"github.com/dubbogo/dubbo-go-pixiu-filter/pkg/api/config"

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

import (
	"github.com/apache/dubbo-go-pixiu/pkg/client"
	"github.com/apache/dubbo-go-pixiu/pkg/common/mock"
)

func TestReg(t *testing.T) {
	reg := regexp.MustCompile(`^(query|uri)`)
	b := reg.MatchString("Stringquery")
	assert.False(t, b)
	b = reg.MatchString("queryString")
	assert.True(t, b)
	b = reg.MatchString("queryuri")
	assert.True(t, b)

	reg = regexp.MustCompile(`^(query|uri)(String|Int|Long|Double|Time)`)
	b = reg.MatchString("Stringquery")
	assert.False(t, b)
	b = reg.MatchString("queryString")
	assert.True(t, b)
	b = reg.MatchString("queryuri")
	assert.False(t, b)
	b = reg.MatchString("queryuriInt")
	assert.False(t, b)

	reg = regexp.MustCompile(`^(query|uri)(String|Int|Long|Double|Time)\.([\w|\d]+)`)
	b = reg.MatchString("Stringquery")
	assert.False(t, b)
	b = reg.MatchString("queryString")
	assert.False(t, b)
	b = reg.MatchString("queryString.name")
	assert.True(t, b)
	b = reg.MatchString("queryuriInt.age")
	assert.False(t, b)

	reg = regexp.MustCompile(`^([query|uri][\w|\d]+)\.([\w|\d]+)$`)
	b = reg.MatchString("queryStrings.name")
	assert.True(t, b)
	b = reg.MatchString("uriInt.")
	assert.False(t, b)
	b = reg.MatchString("queryStrings")
	assert.False(t, b)

	param := reg.FindStringSubmatch("queryString.name")
	for _, p := range param {
		t.Log(p)
	}
}

func TestClose(t *testing.T) {
	client := SingletonDubboClient()
	client.GenericServicePool["key1"] = nil
	client.GenericServicePool["key2"] = nil
	client.GenericServicePool["key3"] = nil
	client.GenericServicePool["key4"] = nil
	assert.Equal(t, 4, len(client.GenericServicePool))
	client.Close()
	assert.Equal(t, 0, len(client.GenericServicePool))
}

func TestMappingParams(t *testing.T) {
	dClient := NewDubboClient()
	r, _ := http.NewRequest("GET", "/mock/test?id=12345&age=19", bytes.NewReader([]byte("")))
	api := mock.GetMockAPI(config.MethodGet, "/mock/test")
	api.IntegrationRequest.MappingParams = []config.MappingParam{
		{
			Name:    "queryStrings.id",
			MapTo:   "0",
			MapType: "string",
		},
		{
			Name:    "queryStrings.age",
			MapTo:   "1",
			MapType: "int",
		},
	}
	req := client.NewReq(context.TODO(), r, api)
	params, err := dClient.MapParams(req)
	assert.Nil(t, err)
	assert.Equal(t, params.(*dubboTarget).Values[0], "12345")
	assert.Equal(t, params.(*dubboTarget).Values[1], int(19))

	r, _ = http.NewRequest("GET", "/mock/test?id=12345&age=19", bytes.NewReader([]byte("")))
	api = mock.GetMockAPI(config.MethodGet, "/mock/test")
	api.IntegrationRequest.MappingParams = []config.MappingParam{
		{
			Name:    "queryStrings.id",
			MapTo:   "0",
			MapType: "string",
		},
		{
			Name:    "queryStrings.age",
			MapTo:   "1",
			MapType: "int",
		},
		{
			Name:    "headers.Auth",
			MapTo:   "2",
			MapType: "string",
		},
	}
	r.Header.Set("Auth", "1234567")
	req = client.NewReq(context.TODO(), r, api)
	params, err = dClient.MapParams(req)
	assert.Nil(t, err)
	assert.Equal(t, params.(*dubboTarget).Values[0], "12345")
	assert.Equal(t, params.(*dubboTarget).Values[1], int(19))
	assert.Equal(t, params.(*dubboTarget).Values[2], "1234567")

	r, _ = http.NewRequest("POST", "/mock/test?id=12345&age=19", bytes.NewReader([]byte(`{"sex": "male", "name":{"firstName": "Joe", "lastName": "Biden"}}`)))
	api = mock.GetMockAPI(config.MethodGet, "/mock/test")
	api.IntegrationRequest.MappingParams = []config.MappingParam{
		{
			Name:    "queryStrings.id",
			MapTo:   "0",
			MapType: "string",
		},
		{
			Name:    "queryStrings.age",
			MapTo:   "1",
			MapType: "int",
		},
		{
			Name:    "headers.Auth",
			MapTo:   "2",
			MapType: "string",
		},
		{
			Name:    "requestBody.sex",
			MapTo:   "3",
			MapType: "string",
		},
		{
			Name:    "requestBody.name.firstName",
			MapTo:   "4",
			MapType: "java.lang.String",
		},
	}
	r.Header.Set("Auth", "1234567")
	req = client.NewReq(context.TODO(), r, api)
	params, err = dClient.MapParams(req)
	assert.Nil(t, err)
	assert.Equal(t, params.(*dubboTarget).Values[0], "12345")
	assert.Equal(t, params.(*dubboTarget).Values[1], int(19))
	assert.Equal(t, params.(*dubboTarget).Values[2], "1234567")
	assert.Equal(t, params.(*dubboTarget).Values[3], "male")
	assert.Equal(t, params.(*dubboTarget).Values[4], "Joe")

	r, _ = http.NewRequest("POST", "/mock/test?id=12345&age=19", bytes.NewReader([]byte(`{"sex": "male", "name":{"firstName": "Joe", "lastName": "Biden"}}`)))
	api = mock.GetMockAPI(config.MethodGet, "/mock/test")
	api.IntegrationRequest.MappingParams = []config.MappingParam{
		{
			Name:  "queryStrings.id",
			MapTo: "opt.method",
		},
		{
			Name:  "queryStrings.age",
			MapTo: "opt.application",
		},
		{
			Name:  "headers.Auth",
			MapTo: "opt.group",
		},
		{
			Name:  "requestBody.sex",
			MapTo: "opt.values",
		},
		{
			Name:  "requestBody.name.firstName",
			MapTo: "opt.interface",
		},
	}
	r.Header.Set("Auth", "1234567")
	req = client.NewReq(context.TODO(), r, api)
	_, err = dClient.MapParams(req)
	assert.Nil(t, err)
	assert.Equal(t, req.API.Method.IntegrationRequest.DubboBackendConfig.ApplicationName, "19")
	assert.Equal(t, req.API.Method.IntegrationRequest.DubboBackendConfig.Group, "1234567")
	assert.Equal(t, req.API.Method.IntegrationRequest.DubboBackendConfig.Interface, "Joe")
	assert.Equal(t, req.API.Method.IntegrationRequest.DubboBackendConfig.Method, "12345")
}

func TestBuildOption(t *testing.T) {
	mp := config.MappingParam{
		Name:    "queryStrings.id",
		MapTo:   "0",
		MapType: "string",
	}
	option := buildOption(mp)
	assert.Nil(t, option)

	mp = config.MappingParam{
		Name:    "queryStrings.id",
		MapTo:   "opt.whatsoever",
		MapType: "",
	}
	option = buildOption(mp)
	assert.Nil(t, option)

	mp = config.MappingParam{
		Name:    "queryStrings.id",
		MapTo:   "opt.interface",
		MapType: "",
	}
	option = buildOption(mp)
	assert.NotNil(t, option)
	_, ok := option.(*interfaceOpt)
	assert.True(t, ok)
}
