package authentication_usecase

import (
	"bytes"
	"chonho/config"
	"context"
	"encoding/json"
	firebase "firebase.google.com/go"
	"firebase.google.com/go/auth"
	"fmt"
	"github.com/gin-gonic/gin"
	"google.golang.org/api/option"
	"io/ioutil"
	"net/http"
	"testing"
)

func Test_useCase_verifyToken(t *testing.T) {
	// init general useCase
	authUseCase := NewAuthenticationUseCase(
		config.JWTKey,
		config.TokenLifeTime,
		nil,
		nil,
		"/Users/phongnguyen/Documents/startup/chonho.com/chonho-api/chonho-250d2-firebase-adminsdk-ibehq-f0f91d8e6a.json",
		nil,
		nil,
	)
	p, e := authUseCase.verifyToken("eyJhbGciOiJSUzI1NiIsImtpZCI6IjM1MDM0MmIwMjU1MDAyYWI3NWUwNTM0YzU4MmVjYzY2Y2YwZTE3ZDIiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vY2hvbmhvLTI1MGQyIiwiYXVkIjoiY2hvbmhvLTI1MGQyIiwiYXV0aF90aW1lIjoxNjMzNzc1MjY1LCJ1c2VyX2lkIjoiRUpySmVHYlNNV01ibjNiQ1VMVkNuejZDN1NwMiIsInN1YiI6IkVKckplR2JTTVdNYm4zYkNVTFZDbno2QzdTcDIiLCJpYXQiOjE2MzM3NzUyNjUsImV4cCI6MTYzMzc3ODg2NSwicGhvbmVfbnVtYmVyIjoiKzg0ODE0ODY0NDM2IiwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJwaG9uZSI6WyIrODQ4MTQ4NjQ0MzYiXX0sInNpZ25faW5fcHJvdmlkZXIiOiJwaG9uZSJ9fQ.gvIMTv19UviAET9om2dJT8huZwOSTqhCrtJd6nc-WHpf7brtNJY1fLvw2a6dXaPXAgUsduHPdlgNO02wvLrz-9a7ta1Ga8xF7Yx2Lxm7qR-1Y8mavrBDSrP8cH83PZAufLJNk3VCLtlstD7efm4awBXDENC6hEu2z4nqPd8_Wr2zv8bcySQnBie02U8hyz3TrdgaI1CES3bDyrdk96Ml4hYIZZaq_GJ5pok82epEgCv4IuwCHiqL4IilsxIoimAZy22fnYdixWd1rVxULcI4J8r0h55iCNxyz5s62giFPyKuJEDkSWEd_uLvOvWnL0Adoc3O7aTRnJwClERglzhZXA", &gin.Context{})
	json, _ := json.Marshal(p)

	t.Log(string(json), e)
	//EPnbKbFZUUUSP8X1rdvDYBiYQ403
}

func TestUserIDToken(t *testing.T) {

	ctx := context.Background()

	opt := option.WithCredentialsFile("/Users/phongnguyen/Documents/startup/chonho.com/chonho-api/cho-nho-app-firebase-adminsdk-3jaz3-e76fb755e3.json")
	app, err := firebase.NewApp(ctx, nil, opt)

	client, err := app.Auth(ctx)
	if err != nil {
		t.Fatal(err)
	}

	user, err := client.CreateUser(ctx, (&auth.UserToCreate{}).PhoneNumber("+84852222116"))
	if err != nil {
		t.Fatal(err)
	}

	tokenString, err := client.CustomToken(ctx, user.UID)
	if err != nil {
		t.Fatal(err)
	}

	idToken, err := signInWithCustomToken(tokenString)
	if err != nil {
		t.Fatal(err)
	}

	fmt.Printf("token: %s\n", idToken)

	token, err := client.VerifyIDToken(ctx, idToken)
	if err != nil {
		t.Fatal(err)
	}

	fmt.Printf("%+v\n", token)
}

const (
	verifyCustomTokenURL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=%s"
)

var (
	apiKey = "AIzaSyBVZFLTXOk3BWShjny7K1_MVyhF0xcHlNI"
)

// see https://github.com/firebase/firebase-admin-go/blob/1d2a52c3c8195451b5ad2e0a173906bd6eb9529d/integration/auth/auth_test.go#L199
func signInWithCustomToken(token string) (string, error) {
	req, err := json.Marshal(map[string]interface{}{
		"token":             token,
		"returnSecureToken": true,
	})
	if err != nil {
		return "", err
	}

	resp, err := postRequest(fmt.Sprintf(verifyCustomTokenURL, apiKey), req)
	if err != nil {
		return "", err
	}
	var respBody struct {
		IDToken string `json:"idToken"`
	}
	if err := json.Unmarshal(resp, &respBody); err != nil {
		return "", err
	}
	return respBody.IDToken, err
}

func postRequest(url string, req []byte) ([]byte, error) {
	resp, err := http.Post(url, "application/json", bytes.NewBuffer(req))
	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("unexpected http status code: %d", resp.StatusCode)
	}
	return ioutil.ReadAll(resp.Body)
}
