package Friends_test

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"testing"
	"time"

	"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database"
	"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder"
	"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models"
	"git.tovijaeschke.xyz/tovi/Capsule/Backend/Tests"
)

func Test_FriendRequestList(t *testing.T) {
	client, ts, err := Tests.InitTestEnv()
	if err != nil {
		t.Errorf("Expected nil, recieved %s", err.Error())
		return
	}

	u, err := Database.GetUserByUsername("test")
	if err != nil {
		t.Errorf("Expected nil, recieved %s", err.Error())
		return
	}

	key, err := Seeder.GenerateAesKey()
	if err != nil {
		t.Errorf("Expected nil, recieved %s", err.Error())
		return
	}

	for i := 0; i < 30; i++ {
		u2, err := Tests.InitTestCreateUser(fmt.Sprintf("test%d", i))

		decodedPublicKey := Seeder.GetPubKey()

		encPublicKey, err := key.AesEncrypt([]byte(Seeder.PublicKey))
		if err != nil {
			t.Errorf("Expected nil, recieved %s", err.Error())
			return
		}

		friendReq := Models.FriendRequest{
			UserID: u.ID,
			FriendID: base64.StdEncoding.EncodeToString(
				Seeder.EncryptWithPublicKey(
					[]byte(u2.ID.String()),
					decodedPublicKey,
				),
			),
			FriendUsername: base64.StdEncoding.EncodeToString(
				Seeder.EncryptWithPublicKey(
					[]byte(u2.Username),
					decodedPublicKey,
				),
			),
			FriendPublicAsymmetricKey: base64.StdEncoding.EncodeToString(
				encPublicKey,
			),
			SymmetricKey: base64.StdEncoding.EncodeToString(
				Seeder.EncryptWithPublicKey(key.Key, decodedPublicKey),
			),
		}

		if i > 20 {
			friendReq.AcceptedAt.Time = time.Now()
			friendReq.AcceptedAt.Valid = true
		}

		err = Database.CreateFriendRequest(&friendReq)
		if err != nil {
			t.Errorf("Expected nil, recieved %s", err.Error())
			return
		}
	}

	req, _ := http.NewRequest("GET", ts.URL+"/api/v1/auth/friend_requests", nil)

	resp, err := client.Do(req)
	if err != nil {
		t.Errorf("Expected nil, recieved %s", err.Error())
		return
	}

	if resp.StatusCode != http.StatusOK {
		t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode)
		return
	}

	requestBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode)
		return
	}

	var users []Models.FriendRequest

	json.Unmarshal(requestBody, &users)

	if len(users) != 20 {
		t.Errorf("Expected %d, recieved %d", 1, len(users))
		return
	}

	for i := 0; i < 20; i++ {
		eq := true
		if i > 8 {
			eq = false
		}
		if users[i].AcceptedAt.Valid != eq {
			t.Errorf(
				"Expected %v, recieved %v, on user %d",
				eq, users[i].AcceptedAt.Valid,
				i,
			)
			return
		}
	}
}
