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

import (
	"encoding/base64"
	"fmt"
	"testing"
	"time"
)

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

import (
	"github.com/apache/dubbo-go/cluster/router"
	"github.com/apache/dubbo-go/cluster/router/condition"
	"github.com/apache/dubbo-go/common"
	"github.com/apache/dubbo-go/common/config"
	"github.com/apache/dubbo-go/common/constant"
	"github.com/apache/dubbo-go/common/extension"
	_ "github.com/apache/dubbo-go/config_center/zookeeper"
	"github.com/apache/dubbo-go/protocol"
	"github.com/apache/dubbo-go/protocol/invocation"
	"github.com/apache/dubbo-go/remoting/zookeeper"
)

const (
	localIP    = "127.0.0.1"
	test1234IP = "1.2.3.4"
	test1111IP = "1.1.1.1"
	test0000IP = "0.0.0.0"
	port20000  = 20000

	path             = "/dubbo/config/dubbo/test-condition.condition-router"
	zkFormat         = "zookeeper://%s:%d"
	consumerFormat   = "consumer://%s/com.foo.BarService"
	dubboForamt      = "dubbo://%s:%d/com.foo.BarService"
	anyUrlFormat     = "condition://%s/com.foo.BarService"
	zk               = "zookeeper"
	applicationKey   = "test-condition"
	applicationField = "application"
	forceField       = "force"
	forceValue       = "true"
)

func TestNewRouterChain(t *testing.T) {
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	assert.NoError(t, err)
	err = z.Create(path)
	assert.NoError(t, err)
	testyml := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
conditions:
  - => host != 172.22.3.91
`

	_, err = z.Conn.Set(path, []byte(testyml), 0)
	assert.NoError(t, err)
	defer func() {
		_ = ts.Stop()
		z.Close()
	}()

	zkUrl, _ := common.NewURL(fmt.Sprintf(zkFormat, localIP, ts.Servers[0].Port))
	configuration, err := extension.GetConfigCenterFactory(zk).GetDynamicConfiguration(zkUrl)
	config.GetEnvInstance().SetDynamicConfiguration(configuration)

	assert.Nil(t, err)
	assert.NotNil(t, configuration)

	chain, err := NewRouterChain(getRouteUrl(applicationKey))
	assert.Nil(t, err)
	assert.Equal(t, 1, len(chain.routers))
	appRouter := chain.routers[0].(*condition.AppRouter)

	assert.NotNil(t, appRouter)
	assert.NotNil(t, appRouter.RouterRule())
	rule := appRouter.RouterRule()
	assert.Equal(t, "application", rule.Scope)
	assert.True(t, rule.Force)
	assert.True(t, rule.Enabled)
	assert.True(t, rule.Valid)

	assert.Equal(t, testyml, rule.RawRule)
	assert.Equal(t, false, rule.Runtime)
	assert.Equal(t, false, rule.Dynamic)
	assert.Equal(t, "mock-app", rule.Key)
}

func TestNewRouterChainURLNil(t *testing.T) {
	chain, err := NewRouterChain(nil)
	assert.NoError(t, err)
	assert.NotNil(t, chain)
}

func TestRouterChainAddRouters(t *testing.T) {
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	assert.NoError(t, err)
	err = z.Create(path)
	assert.NoError(t, err)

	testyml := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
conditions:
  - => host != 172.22.3.91
`

	_, err = z.Conn.Set(path, []byte(testyml), 0)
	assert.NoError(t, err)
	defer func() {
		_ = ts.Stop()
		assert.NoError(t, err)
		z.Close()
	}()

	zkUrl, _ := common.NewURL(fmt.Sprintf(zkFormat, localIP, ts.Servers[0].Port))
	configuration, err := extension.GetConfigCenterFactory(zk).GetDynamicConfiguration(zkUrl)
	assert.NoError(t, err)
	config.GetEnvInstance().SetDynamicConfiguration(configuration)

	chain, err := NewRouterChain(getConditionRouteUrl(applicationKey))
	assert.Nil(t, err)
	assert.Equal(t, 2, len(chain.routers))

	url := getConditionRouteUrl(applicationKey)
	assert.NotNil(t, url)
	factory := extension.GetRouterFactory(url.Protocol)
	notify := make(chan struct{})
	go func() {
		for range notify {
		}
	}()
	r, err := factory.NewPriorityRouter(url, notify)
	assert.Nil(t, err)
	assert.NotNil(t, r)

	routers := make([]router.PriorityRouter, 0)
	routers = append(routers, r)
	chain.AddRouters(routers)
	assert.Equal(t, 3, len(chain.routers))
}

func TestRouterChainRoute(t *testing.T) {
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	defer func() {
		err = ts.Stop()
		assert.NoError(t, err)
		z.Close()
	}()

	zkUrl, _ := common.NewURL(fmt.Sprintf(zkFormat, localIP, ts.Servers[0].Port))
	configuration, err := extension.GetConfigCenterFactory(zk).GetDynamicConfiguration(zkUrl)
	assert.NoError(t, err)
	config.GetEnvInstance().SetDynamicConfiguration(configuration)

	chain, err := NewRouterChain(getConditionRouteUrl(applicationKey))
	assert.Nil(t, err)
	assert.Equal(t, 1, len(chain.routers))

	url := getConditionRouteUrl(applicationKey)
	assert.NotNil(t, url)

	var invokers []protocol.Invoker
	dubboURL, _ := common.NewURL(fmt.Sprintf(dubboForamt, test1234IP, port20000))
	invokers = append(invokers, protocol.NewBaseInvoker(dubboURL))
	chain.SetInvokers(invokers)
	chain.buildCache()

	targetURL, _ := common.NewURL(fmt.Sprintf(consumerFormat, test1111IP))
	inv := &invocation.RPCInvocation{}
	finalInvokers := chain.Route(targetURL, inv)

	assert.Equal(t, 1, len(finalInvokers))
}

func TestRouterChainRouteAppRouter(t *testing.T) {
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	assert.NoError(t, err)
	err = z.Create(path)
	assert.NoError(t, err)

	testyml := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
conditions:
  - => host = 1.1.1.1 => host != 1.2.3.4
`

	_, err = z.Conn.Set(path, []byte(testyml), 0)
	assert.NoError(t, err)
	defer func() {
		_ = ts.Stop()
		assert.NoError(t, err)
		z.Close()
	}()

	zkUrl, _ := common.NewURL(fmt.Sprintf(zkFormat, localIP, ts.Servers[0].Port))
	configuration, err := extension.GetConfigCenterFactory(zk).GetDynamicConfiguration(zkUrl)
	assert.NoError(t, err)
	config.GetEnvInstance().SetDynamicConfiguration(configuration)

	chain, err := NewRouterChain(getConditionRouteUrl(applicationKey))
	assert.Nil(t, err)
	assert.Equal(t, 2, len(chain.routers))

	var invokers []protocol.Invoker
	dubboURL, _ := common.NewURL(fmt.Sprintf(dubboForamt, test1234IP, port20000))
	invokers = append(invokers, protocol.NewBaseInvoker(dubboURL))
	chain.SetInvokers(invokers)
	chain.buildCache()

	targetURL, _ := common.NewURL(fmt.Sprintf(consumerFormat, test1111IP))
	inv := &invocation.RPCInvocation{}
	finalInvokers := chain.Route(targetURL, inv)

	assert.Equal(t, 0, len(finalInvokers))
}

func TestRouterChainRouteNoRoute(t *testing.T) {
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	assert.Nil(t, err)
	defer func() {
		_ = ts.Stop()
		assert.NoError(t, err)
		z.Close()
	}()

	zkUrl, _ := common.NewURL(fmt.Sprintf(zkFormat, localIP, ts.Servers[0].Port))
	configuration, err := extension.GetConfigCenterFactory(zk).GetDynamicConfiguration(zkUrl)
	config.GetEnvInstance().SetDynamicConfiguration(configuration)
	assert.Nil(t, err)

	chain, err := NewRouterChain(getConditionNoRouteUrl(applicationKey))
	assert.Nil(t, err)
	assert.Equal(t, 1, len(chain.routers))

	url := getConditionRouteUrl(applicationKey)
	assert.NotNil(t, url)

	var invokers []protocol.Invoker
	dubboURL, _ := common.NewURL(fmt.Sprintf(dubboForamt, test1234IP, port20000))
	invokers = append(invokers, protocol.NewBaseInvoker(dubboURL))
	chain.SetInvokers(invokers)
	chain.buildCache()

	targetURL, _ := common.NewURL(fmt.Sprintf(consumerFormat, test1111IP))
	inv := &invocation.RPCInvocation{}
	finalInvokers := chain.Route(targetURL, inv)

	assert.Equal(t, 0, len(finalInvokers))
}

func getConditionNoRouteUrl(applicationKey string) *common.URL {
	url, _ := common.NewURL(fmt.Sprintf(anyUrlFormat, test0000IP))
	url.AddParam(applicationField, applicationKey)
	url.AddParam(forceField, forceValue)
	rule := base64.URLEncoding.EncodeToString([]byte("host = 1.1.1.1 => host != 1.2.3.4"))
	url.AddParam(constant.RULE_KEY, rule)
	return url
}

func getConditionRouteUrl(applicationKey string) *common.URL {
	url, _ := common.NewURL(fmt.Sprintf(anyUrlFormat, test0000IP))
	url.AddParam(applicationField, applicationKey)
	url.AddParam(forceField, forceValue)
	rule := base64.URLEncoding.EncodeToString([]byte("host = 1.1.1.1 => host = 1.2.3.4"))
	url.AddParam(constant.RULE_KEY, rule)
	return url
}

func getRouteUrl(applicationKey string) *common.URL {
	url, _ := common.NewURL(fmt.Sprintf(anyUrlFormat, test0000IP))
	url.AddParam(applicationField, applicationKey)
	url.AddParam(forceField, forceValue)
	return url
}
