package login

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gin-gonic/gin"
	"github.com/onsi/gomega"
	"golang.org/x/oauth2"

	"github.com/pingcap-inc/clinic/pkg/auth/oauth"
	"github.com/pingcap-inc/clinic/pkg/auth/session"
	"github.com/pingcap-inc/clinic/pkg/config"
	"github.com/pingcap-inc/clinic/pkg/rbac"
)

func TestLoginOut(t *testing.T) {
	g := gomega.NewWithT(t)
	w := httptest.NewRecorder()
	context, _ := gin.CreateTestContext(w)
	context.Set(session.CtxUserKey, &session.CtxUser{
		Username:        "user01",
		UserID:          1,
		Email:           "test01",
		Internal:        true,
		OrgIDInApiToken: 1,
	})
	context.Request = httptest.NewRequest(http.MethodPost, "http://127.0.0.1:8080", nil)
	service.LoginOut(context)
	if w.Body != nil {
		body, err := io.ReadAll(w.Body)
		if err != nil {
			panic(err)
		}
		fmt.Println("respBody: ", string(body))
	}
	g.Expect(w.Code).To(gomega.Equal(http.StatusOK))
}

func TestOAuthConfig(t *testing.T) {
	g := gomega.NewWithT(t)
	w := httptest.NewRecorder()
	context, _ := gin.CreateTestContext(w)
	context.Set(session.CtxUserKey, &session.CtxUser{
		Username:        "user01",
		UserID:          1,
		Email:           "test01",
		Internal:        true,
		OrgIDInApiToken: 1,
	})
	params := []gin.Param{
		{
			Key:   "name",
			Value: "internal",
		},
	}
	context.Params = params
	context.Request = httptest.NewRequest(http.MethodGet, "http://127.0.0.1:8080?redirect_uri=\"test_uri\"", nil)
	service.OAuthConfig(context)
	if w.Body != nil {
		body, err := io.ReadAll(w.Body)
		if err != nil {
			panic(err)
		}
		fmt.Println("respBody: ", string(body))
	}
	g.Expect(w.Code).To(gomega.Equal(http.StatusOK))
}

func TestValidate(t *testing.T) {
	g := gomega.NewWithT(t)
	w := httptest.NewRecorder()
	context, _ := gin.CreateTestContext(w)
	context.Set(session.CtxUserKey, &session.CtxUser{
		Username:        "user01",
		UserID:          1,
		Email:           "test01",
		Internal:        true,
		OrgIDInApiToken: 1,
	})
	params := []gin.Param{
		{
			Key:   "name",
			Value: "internal",
		},
	}
	reqMap := map[string]any{
		"code":         "test_code",
		"redirect_uri": "test_uri",
		"state":        "aaa.bbb.ccc",
	}
	body, err := json.Marshal(reqMap)
	if err != nil {
		fmt.Println("TestPostReq json.Marshal err:", err)
		return
	}
	oau1 := config.OAuthConfig{
		ApiUrl:       "test_url01",
		ClientSecret: "test_secret",
	}
	oau2 := oauth2.Config{}
	oauth.Authers["internal"] = oauth.NewInternalOAuth(oau1, oau2, &rbac.RbacMock{})
	context.Params = params
	context.Request = httptest.NewRequest(http.MethodPost, "http://127.0.0.1:8080", bytes.NewReader(body))
	service.OAuthValidate(context)
	if w.Body != nil {
		body, err := io.ReadAll(w.Body)
		if err != nil {
			panic(err)
		}
		fmt.Println("respBody: ", string(body))
	}
	g.Expect(w.Code).To(gomega.Equal(http.StatusOK))
}
