package api

import (
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/tj/assert"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/dbaas/central/config"
)

func TestBillingProxyRedirectNotExists(t *testing.T) {
	assert := assert.New(t)
	router := gin.New()
	router.Any("/api_proxy/billing/*any", BillingProxy)
	testServer := gin.New()
	// use random port
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		panic(err)
	}
	config.Global().BillingConfig.Billing2BaseURL = "http://" + listener.Addr().String()
	go http.Serve(listener, testServer) //nolint
	frontend := httptest.NewServer(router)
	defer frontend.Close()
	req, err := http.NewRequest("GET", frontend.URL+"/api_proxy/billing/api/v1/billing/tenants/10/invoices", nil)
	assert.NoError(err)
	frontendClient := frontend.Client()
	result, err := frontendClient.Do(req)
	assert.NoError(err)
	_ = assert
	assert.Equal(result.StatusCode, 404)
}

func TestBillingProxy(t *testing.T) {
	assert := assert.New(t)
	router := gin.New()
	// router.Use(MustHaveAdminPermissions())
	router.Any("/api_proxy/billing/*any", BillingProxy)
	testServer := gin.New()
	testServer.GET("/api/v1/billing/tenants/10/invoices", func(c *gin.Context) {
		c.String(http.StatusOK, "test_res")
	})
	// use random port
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		panic(err)
	}
	config.Global().BillingConfig.Billing2BaseURL = "http://" + listener.Addr().String()
	go http.Serve(listener, testServer) //nolint
	frontend := httptest.NewServer(router)
	defer frontend.Close()
	req, err := http.NewRequest("GET", frontend.URL+"/api_proxy/billing/api/v1/billing/tenants/10/invoices", nil)
	assert.NoError(err)
	frontendClient := frontend.Client()
	result, err := frontendClient.Do(req)
	assert.NoError(err)
	_ = assert
	body, err := ioutil.ReadAll(result.Body)
	assert.NoError(err)
	assert.Equal(string(body), "test_res")
	assert.Equal(result.StatusCode, 200)
}

func TestBillingProxyPermission(t *testing.T) {
	assert := assert.New(t)
	router := gin.New()
	router.Use(MustHaveAdminPermissions())
	router.Any("/api_proxy/billing/*any", BillingProxy)
	testServer := gin.New()
	testServer.GET("/api/v1/billing/tenants/10/invoices", func(c *gin.Context) {
		c.String(http.StatusOK, "test_res")
	})
	// use random port
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		panic(err)
	}
	config.Global().BillingConfig.Billing2BaseURL = "http://" + listener.Addr().String()
	go http.Serve(listener, testServer) //nolint
	frontend := httptest.NewServer(router)
	defer frontend.Close()
	req, err := http.NewRequest("GET", frontend.URL+"/api_proxy/billing/api/v1/billing/tenants/10/invoices", nil)
	assert.NoError(err)
	frontendClient := frontend.Client()
	result, err := frontendClient.Do(req)
	assert.NoError(err)
	_ = assert
	_, err = ioutil.ReadAll(result.Body)
	assert.NoError(err)
	assert.Equal(result.StatusCode, 401)
}
