package Messages_test

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"net/http"
	"testing"

	"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"
	"github.com/gofrs/uuid"
)

func Test_CreateConversation(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")

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

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

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

	id, err := uuid.NewV4()
	if err != nil {
		t.Errorf("Expected nil, recieved %s", err.Error())
		return
	}

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

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

	userIDCiphertext, err := key.AesEncrypt([]byte(u.ID.String()))
	if err != nil {
		t.Errorf("Expected nil, recieved %s", err.Error())
		return
	}

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

	pubKey := Seeder.GetPubKey()

	d := struct {
		ID                string                          `json:"id"`
		Name              string                          `json:"name"`
		TwoUser           string                          `json:"two_user"`
		Users             []Models.ConversationDetailUser `json:"users"`
		UserConversations []Models.UserConversation       `json:"user_conversations"`
	}{
		ID:      id.String(),
		Name:    base64.StdEncoding.EncodeToString(nameCiphertext),
		TwoUser: base64.StdEncoding.EncodeToString(twoUserCiphertext),
		Users: []Models.ConversationDetailUser{
			{
				ConversationDetailID: id,
				UserID:               base64.StdEncoding.EncodeToString(userIDCiphertext),
				Username:             base64.StdEncoding.EncodeToString(usernameCiphertext),
				AssociationKey:       "",
				PublicKey:            "",
				Admin:                base64.StdEncoding.EncodeToString(adminCiphertext),
			},
		},
		UserConversations: []Models.UserConversation{
			{
				UserID:               u.ID,
				ConversationDetailID: base64.StdEncoding.EncodeToString(conversationDetailIDCiphertext),
				Admin:                base64.StdEncoding.EncodeToString(adminCiphertext),
				SymmetricKey: base64.StdEncoding.EncodeToString(
					Seeder.EncryptWithPublicKey(key.Key, pubKey),
				),
			},
		},
	}

	jsonStr, _ := json.Marshal(d)
	req, _ := http.NewRequest("POST", ts.URL+"/api/v1/auth/conversations", bytes.NewBuffer(jsonStr))
	req.Header.Set("Content-Type", "application/json")

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

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

	var c Models.ConversationDetail
	err = Database.DB.First(&c, "id = ?", id.String()).Error
	if err != nil {
		t.Errorf("Expected conversation detail record, received %s", err.Error())
		return
	}
}
