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

import (
	"fmt"
	"reflect"
	"testing"
)

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

import (
	"github.com/apache/dubbo-go/common/config"
	_ "github.com/apache/dubbo-go/config_center/apollo"
)

func getMockMap() map[string]string {
	baseMockMap := map[string]string{
		"dubbo.registries.shanghai_reg1.protocol":             "mock100",
		"dubbo.reference.com.MockService.MockService.retries": "10",
		"dubbo.com.MockService.MockService.GetUser.retries":   "10",
		"dubbo.consumer.check":                                "false",
		"dubbo.application.name":                              "dubbo",
	}
	return baseMockMap
}

var baseAppConfig = &ApplicationConfig{
	Organization: "dubbo_org",
	Name:         "dubbo",
	Module:       "module",
	Version:      "2.6.0",
	Owner:        "dubbo",
	Environment:  "test",
}

var baseRegistries = map[string]*RegistryConfig{
	"shanghai_reg2": {
		Protocol:   "mock",
		TimeoutStr: "2s",
		Group:      "shanghai_idc",
		Address:    "127.0.0.2:2181",
		Username:   "user1",
		Password:   "pwd1",
	},
	"hangzhou_reg1": {
		Protocol:   "mock",
		TimeoutStr: "2s",
		Group:      "hangzhou_idc",
		Address:    "127.0.0.3:2181",
		Username:   "user1",
		Password:   "pwd1",
	},
	"hangzhou_reg2": {
		Protocol:   "mock",
		TimeoutStr: "2s",
		Group:      "hangzhou_idc",
		Address:    "127.0.0.4:2181",
		Username:   "user1",
		Password:   "pwd1",
	},
}

var baseMockRef = map[string]*ReferenceConfig{
	"MockService": {
		InterfaceName: "com.MockService",
		Protocol:      "mock",
		Cluster:       "failover",
		Loadbalance:   "random",
		Retries:       "3",
		Group:         "huadong_idc",
		Version:       "1.0.0",
		Methods: []*MethodConfig{
			{
				InterfaceId:   "MockService",
				InterfaceName: "com.MockService",
				Name:          "GetUser",
				Retries:       "2",
				LoadBalance:   "random",
			},
			{
				InterfaceId:   "MockService",
				InterfaceName: "com.MockService",
				Name:          "GetUser1",
				Retries:       "2",
				LoadBalance:   "random",
			},
		},
	},
}

func TestRefresh(t *testing.T) {
	c := &BaseConfig{}
	mockMap := getMockMap()
	mockMap["dubbo.shutdown.timeout"] = "12s"

	config.GetEnvInstance().UpdateExternalConfigMap(mockMap)

	father := &ConsumerConfig{
		Check: &[]bool{true}[0],
		BaseConfig: BaseConfig{
			ApplicationConfig: baseAppConfig,
		},
		Registries: baseRegistries,
		References: baseMockRef,
		ShutdownConfig: &ShutdownConfig{
			Timeout:              "12s",
			StepTimeout:          "2s",
			RejectRequestHandler: "mock",
			RejectRequest:        false,
			RequestsFinished:     false,
		},
	}

	c.SetFatherConfig(father)
	c.fresh()
	assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol)
	assert.Equal(t, "10", father.References["MockService"].Retries)

	assert.Equal(t, "10", father.References["MockService"].Methods[0].Retries)
	assert.Equal(t, &[]bool{false}[0], father.Check)
	assert.Equal(t, "dubbo", father.ApplicationConfig.Name)
}

func TestAppExternalRefresh(t *testing.T) {
	c := &BaseConfig{}
	mockMap := getMockMap()
	mockMap["dubbo.reference.com.MockService.retries"] = "5"

	config.GetEnvInstance().UpdateAppExternalConfigMap(mockMap)
	mockMap["dubbo.consumer.check"] = "true"
	config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
	father := &ConsumerConfig{
		Check: &[]bool{true}[0],
		BaseConfig: BaseConfig{
			ApplicationConfig: baseAppConfig,
		},
		Registries: baseRegistries,
		References: baseMockRef,
	}

	c.SetFatherConfig(father)
	c.fresh()
	assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol)
	assert.Equal(t, "10", father.References["MockService"].Retries)

	assert.Equal(t, "10", father.References["MockService"].Methods[0].Retries)
	assert.Equal(t, &[]bool{true}[0], father.Check)
	assert.Equal(t, "dubbo", father.ApplicationConfig.Name)
}

func TestAppExternalWithoutIDRefresh(t *testing.T) {
	c := &BaseConfig{}
	mockMap := getMockMap()
	delete(mockMap, "dubbo.reference.com.MockService.MockService.retries")
	mockMap["dubbo.reference.com.MockService.retries"] = "10"

	config.GetEnvInstance().UpdateAppExternalConfigMap(mockMap)
	mockMap["dubbo.consumer.check"] = "true"
	config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
	father := &ConsumerConfig{
		Check: &[]bool{true}[0],
		BaseConfig: BaseConfig{
			ApplicationConfig: baseAppConfig,
		},
		Registries: baseRegistries,
		References: baseMockRef,
	}

	c.SetFatherConfig(father)
	c.fresh()
	assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol)
	assert.Equal(t, "10", father.References["MockService"].Retries)

	assert.Equal(t, "10", father.References["MockService"].Methods[0].Retries)
	assert.Equal(t, &[]bool{true}[0], father.Check)
	assert.Equal(t, "dubbo", father.ApplicationConfig.Name)
}

func TestRefreshSingleRegistry(t *testing.T) {
	c := &BaseConfig{}
	mockMap := map[string]string{}
	mockMap["dubbo.registry.address"] = "mock100://127.0.0.1:2181"
	mockMap["dubbo.reference.com.MockService.MockService.retries"] = "10"
	mockMap["dubbo.com.MockService.MockService.GetUser.retries"] = "10"
	mockMap["dubbo.consumer.check"] = "false"
	mockMap["dubbo.application.name"] = "dubbo"

	config.GetEnvInstance().UpdateExternalConfigMap(mockMap)

	father := &ConsumerConfig{
		Check: &[]bool{true}[0],
		BaseConfig: BaseConfig{
			ApplicationConfig: baseAppConfig,
		},
		Registries: map[string]*RegistryConfig{},
		Registry:   &RegistryConfig{},
		References: baseMockRef,
	}

	c.SetFatherConfig(father)
	c.fresh()
	assert.Equal(t, "mock100://127.0.0.1:2181", father.Registry.Address)
	assert.Equal(t, "10", father.References["MockService"].Retries)

	assert.Equal(t, "10", father.References["MockService"].Methods[0].Retries)
	assert.Equal(t, &[]bool{false}[0], father.Check)
	assert.Equal(t, "dubbo", father.ApplicationConfig.Name)
}

func TestRefreshProvider(t *testing.T) {
	c := &BaseConfig{}
	mockMap := getMockMap()
	delete(mockMap, "dubbo.reference.com.MockService.MockService.retries")
	mockMap["dubbo.service.com.MockService.MockService.retries"] = "10"
	mockMap["dubbo.protocols.jsonrpc1.name"] = "jsonrpc"
	mockMap["dubbo.protocols.jsonrpc1.ip"] = "127.0.0.1"
	mockMap["dubbo.protocols.jsonrpc1.port"] = "20001"

	config.GetEnvInstance().UpdateExternalConfigMap(mockMap)

	father := &ProviderConfig{
		BaseConfig: BaseConfig{
			ApplicationConfig: baseAppConfig,
		},
		Registries: baseRegistries,
		Services: map[string]*ServiceConfig{
			"MockService": {
				InterfaceName: "com.MockService",
				Protocol:      "mock",
				Cluster:       "failover",
				Loadbalance:   "random",
				Retries:       "3",
				Group:         "huadong_idc",
				Version:       "1.0.0",
				Methods: []*MethodConfig{
					{
						InterfaceId:   "MockService",
						InterfaceName: "com.MockService",
						Name:          "GetUser",
						Retries:       "2",
						LoadBalance:   "random",
					},
					{
						InterfaceId:   "MockService",
						InterfaceName: "com.MockService",
						Name:          "GetUser1",
						Retries:       "2",
						LoadBalance:   "random",
					},
				},
			},
		},
	}

	c.SetFatherConfig(father)
	c.fresh()
	assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol)
	assert.Equal(t, "10", father.Services["MockService"].Retries)

	assert.Equal(t, "10", father.Services["MockService"].Methods[0].Retries)
	assert.Equal(t, "dubbo", father.ApplicationConfig.Name)
	assert.Equal(t, "20001", father.Protocols["jsonrpc1"].Port)
}

func TestInitializeStruct(t *testing.T) {
	testConsumerConfig := &ConsumerConfig{}
	tp := reflect.TypeOf(ConsumerConfig{})
	v := reflect.New(tp)
	initializeStruct(tp, v.Elem())
	fmt.Println(reflect.ValueOf(testConsumerConfig).Elem().Type().String())
	fmt.Println(v.Elem().Type().String())
	reflect.ValueOf(testConsumerConfig).Elem().Set(v.Elem())

	assert.Condition(t, func() (success bool) {
		return testConsumerConfig.Registry != nil
	})
	assert.Condition(t, func() (success bool) {
		return testConsumerConfig.Registries != nil
	})
	assert.Condition(t, func() (success bool) {
		return testConsumerConfig.References != nil
	})
}
