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

import (
	"testing"
)

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

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

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

func TestNewLocalMemoryAPIDiscoveryService(t *testing.T) {
	l := NewLocalMemoryAPIDiscoveryService()
	assert.NotNil(t, l)
	assert.NotNil(t, l.router)
}

func TestAddAPI(t *testing.T) {
	l := NewLocalMemoryAPIDiscoveryService()
	err := l.AddAPI(mock.GetMockAPI(fc.MethodPut, "/this/is/test"))
	assert.Nil(t, err)
	_, found := l.router.FindAPI("/this/is/test", fc.MethodPut)
	assert.True(t, found)
}

func TestGetAPI(t *testing.T) {
	l := NewLocalMemoryAPIDiscoveryService()
	err := l.AddAPI(mock.GetMockAPI(fc.MethodPut, "/this/is/test"))
	assert.Nil(t, err)
	_, err = l.GetAPI("/this/is/test", fc.MethodPut)
	assert.Nil(t, err)

	_, err = l.GetAPI("/this/is/test/or/else", fc.MethodPut)
	assert.NotNil(t, err)
}

func TestLoadAPI(t *testing.T) {
	Init()
	apiC, err := config.LoadAPIConfigFromFile("../../config/mock/api_config.yml")
	assert.Empty(t, err)
	err = InitAPIsFromConfig(*apiC)
	assert.Nil(t, err)
	apiDisSrv := extension.GetMustAPIDiscoveryService(constant.LocalMemoryApiDiscoveryService)
	rsp, _ := apiDisSrv.GetAPI("/", fc.MethodGet)
	assert.NotNil(t, rsp.URLPattern)
	rsp, _ = apiDisSrv.GetAPI("/mockTest", fc.MethodGet)
	assert.NotNil(t, rsp.URLPattern)
	rsp, _ = apiDisSrv.GetAPI("/mockTest", fc.MethodPost)
	assert.NotNil(t, rsp.URLPattern)
	rsp, _ = apiDisSrv.GetAPI("/mockTest/12345", fc.MethodGet)
	assert.NotNil(t, rsp.URLPattern)
}

func TestLoadAPIFromResource(t *testing.T) {
	apiDiscSrv := NewLocalMemoryAPIDiscoveryService()
	mockMethod1 := mock.GetMockAPI(fc.MethodPut, "").Method
	mockMethod2 := mock.GetMockAPI(fc.MethodPost, "").Method
	mockMethod3 := mock.GetMockAPI(fc.MethodGet, "").Method
	tempResources := []fc.Resource{
		{
			Type:        "Restful",
			Path:        "/",
			Description: "test only",
			Methods: []fc.Method{
				mockMethod1,
				mockMethod2,
				mockMethod3,
			},
			Resources: []fc.Resource{
				{
					Type:        "Restful",
					Path:        "/mock",
					Description: "test only",
					Methods: []fc.Method{
						mockMethod1,
						mockMethod2,
						mockMethod3,
					},
				},
				{
					Type:        "Restful",
					Path:        "/mock2",
					Description: "test only",
					Methods: []fc.Method{
						mockMethod1,
					},
					Resources: []fc.Resource{
						{
							Type:        "Restful",
							Path:        "/:id",
							Description: "test only",
							Methods: []fc.Method{
								mockMethod1,
							},
						},
					},
				},
			},
		},
	}
	err := loadAPIFromResource("", tempResources, nil, apiDiscSrv)
	assert.Nil(t, err)
	rsp, _ := apiDiscSrv.GetAPI("/", fc.MethodPut)
	assert.Equal(t, rsp.URLPattern, "/")
	rsp, _ = apiDiscSrv.GetAPI("/", fc.MethodGet)
	assert.Equal(t, rsp.URLPattern, "/")
	rsp, _ = apiDiscSrv.GetAPI("/mock", fc.MethodGet)
	assert.Equal(t, rsp.URLPattern, "/mock")
	rsp, _ = apiDiscSrv.GetAPI("/mock2/12345", fc.MethodPut)
	assert.Equal(t, rsp.URLPattern, "/mock2/:id")

	tempResources = []fc.Resource{
		{
			Type:        "Restful",
			Path:        "/mock",
			Description: "test only",
			Methods: []fc.Method{
				mockMethod1,
			},
			Resources: []fc.Resource{
				{
					Type:        "Restful",
					Path:        ":id",
					Description: "test only",
					Methods: []fc.Method{
						mockMethod1,
					},
				},
				{
					Type:        "Restful",
					Path:        ":ik",
					Description: "test only",
					Methods: []fc.Method{
						mockMethod1,
					},
				},
			},
		},
	}
	apiDiscSrv = NewLocalMemoryAPIDiscoveryService()
	err = loadAPIFromResource("", tempResources, nil, apiDiscSrv)
	assert.EqualError(t, err, "path :id in /mock doesn't start with /; path :ik in /mock doesn't start with /")
}

func TestLoadAPIFromMethods(t *testing.T) {
	tempMethods := []fc.Method{
		mock.GetMockAPI(fc.MethodPut, "").Method,
		mock.GetMockAPI(fc.MethodGet, "").Method,
		mock.GetMockAPI(fc.MethodPut, "").Method,
	}
	apiDiscSrv := NewLocalMemoryAPIDiscoveryService()
	err := loadAPIFromMethods("/mock", tempMethods, nil, apiDiscSrv)
	rsp, _ := apiDiscSrv.GetAPI("/mock", fc.MethodPut)
	assert.Equal(t, rsp.URLPattern, "/mock")
	rsp, _ = apiDiscSrv.GetAPI("/mock", fc.MethodGet)
	assert.Equal(t, rsp.URLPattern, "/mock")
	assert.EqualError(t, err, "path: /mock, Method: PUT, error: Method PUT already exists in path /mock")
}
