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

import (
	"fmt"
	"testing"
	"time"
)

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

import (
	"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"
	_ "github.com/apache/dubbo-go/config_center/zookeeper"
	"github.com/apache/dubbo-go/remoting"
	"github.com/apache/dubbo-go/remoting/zookeeper"
)

const (
	routerPath    = "/dubbo/config/dubbo/test-condition.condition-router"
	routerLocalIP = "127.0.0.1"
	routerZk      = "zookeeper"
	routerKey     = "test-condition"
)

var (
	zkFormat        = "zookeeper://%s:%d"
	conditionFormat = "condition://%s/com.foo.BarService"
)

func TestNewAppRouter(t *testing.T) {

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

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

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

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

	appRouteURL := getAppRouteURL(routerKey)
	notify := make(chan struct{})
	go func() {
		for range notify {
		}
	}()
	appRouter, err := NewAppRouter(appRouteURL, notify)
	assert.Nil(t, err)
	assert.NotNil(t, 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)
	assert.Equal(t, 0, rule.Priority)
}

func TestGenerateConditions(t *testing.T) {

	testYML := `scope: application
key: mock-app
enabled: true
force: true
runtime: false
conditions:
  - => host != 172.22.3.91
  - host = 192.168.199.208 => host = 192.168.199.208
`
	ts, z, _, err := zookeeper.NewMockZookeeperClient("test", 15*time.Second)
	assert.NoError(t, err)
	err = z.Create(routerPath)
	assert.NoError(t, err)

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

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

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

	appRouteURL := getAppRouteURL(routerKey)
	notify := make(chan struct{})
	go func() {
		for range notify {
		}
	}()
	appRouter, err := NewAppRouter(appRouteURL, notify)
	assert.Nil(t, err)
	assert.NotNil(t, appRouter)

	rule, err := getRule(testYML)
	assert.Nil(t, err)
	appRouter.generateConditions(rule)

	assert.Equal(t, 2, len(appRouter.conditionRouters))
}

func TestProcess(t *testing.T) {

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

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

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

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

	appRouteURL := getAppRouteURL(routerKey)
	notify := make(chan struct{})
	go func() {
		for range notify {
		}
	}()
	appRouter, err := NewAppRouter(appRouteURL, notify)
	assert.Nil(t, err)
	assert.NotNil(t, appRouter)

	assert.Equal(t, 1, len(appRouter.conditionRouters))

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

	appRouter.Process(&config_center.ConfigChangeEvent{ConfigType: remoting.EventTypeDel})

	assert.Equal(t, 0, len(appRouter.conditionRouters))

	appRouter.Process(&config_center.ConfigChangeEvent{Value: testNewYML, ConfigType: remoting.EventTypeAdd})

	assert.Equal(t, 2, len(appRouter.conditionRouters))
}

func getAppRouteURL(applicationKey string) *common.URL {
	url, _ := common.NewURL(fmt.Sprintf(conditionFormat, constant.ANYHOST_VALUE))
	url.AddParam("application", applicationKey)
	url.AddParam("force", "true")
	return url
}
