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

import (
	"bytes"
	"math"
	"net/http"
	"testing"
)

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

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

import (
	"github.com/apache/dubbo-go-pixiu/pkg/context/mock"
	"github.com/apache/dubbo-go-pixiu/pkg/filter/recovery"
)

func TestHeader(t *testing.T) {
	api := router.API{
		URLPattern: "/mock/:id/:name",
		Method:     getMockMethod(config.MethodGet),
		Headers:    map[string]string{},
	}
	request, err := http.NewRequest("POST", "http://www.dubbogopixiu.com/mock/test?name=tc", bytes.NewReader([]byte("{\"id\":\"12345\"}")))
	assert.NoError(t, err)
	c := mock.GetMockHTTPContext(request, New().Do(), recovery.New().Do())
	c.API(api)
	c.Next()
	assert.Equal(t, int8(len(c.Filters)*2), c.BaseContext.Index)

	request.Header.Set("filter", "test")
	api.Headers["filter"] = "test"
	c1 := mock.GetMockHTTPContext(request, New().Do(), recovery.New().Do())
	c1.API(api)
	c1.Next()
	assert.Equal(t, int8(len(c1.Filters)*2-1), c1.BaseContext.Index)

	request.Header.Set("filter", "test1")
	c2 := mock.GetMockHTTPContext(request, New().Do(), recovery.New().Do())
	c2.API(api)
	c2.Next()
	assert.Equal(t, int8(math.MaxInt8/2+1), c2.BaseContext.Index)
}

func getMockMethod(verb config.HTTPVerb) config.Method {
	inbound := config.InboundRequest{}
	integration := config.IntegrationRequest{}
	return config.Method{
		OnAir:              true,
		HTTPVerb:           verb,
		InboundRequest:     inbound,
		IntegrationRequest: integration,
	}
}
