package Messages_test

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"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"
	"github.com/gofrs/uuid"
)

// TODO: Write test for message expiry

func Test_CreateMessage(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
	}

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

	senderIDCiphertext, err := key.AesEncrypt([]byte(u.ID.String()))
	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
	}

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

	d := []struct {
		MessageData struct {
			ID           uuid.UUID `json:"id"`
			Data         string    `json:"data"`
			SenderID     string    `json:"sender_id"`
			SymmetricKey string    `json:"symmetric_key"`
		} `json:"message_data"`
		Messages []struct {
			ID             uuid.UUID `json:"id"`
			MessageDataID  uuid.UUID `json:"message_data_id"`
			SymmetricKey   string    `json:"symmetric_key"`
			AssociationKey string    `json:"association_key"`
			Expiry         time.Time `json:"expiry"`
		} `json:"message"`
	}{
		{
			MessageData: struct {
				ID           uuid.UUID `json:"id"`
				Data         string    `json:"data"`
				SenderID     string    `json:"sender_id"`
				SymmetricKey string    `json:"symmetric_key"`
			}{
				ID:           id,
				Data:         base64.StdEncoding.EncodeToString(dataCiphertext),
				SenderID:     base64.StdEncoding.EncodeToString(senderIDCiphertext),
				SymmetricKey: "",
			},
			Messages: []struct {
				ID             uuid.UUID `json:"id"`
				MessageDataID  uuid.UUID `json:"message_data_id"`
				SymmetricKey   string    `json:"symmetric_key"`
				AssociationKey string    `json:"association_key"`
				Expiry         time.Time `json:"expiry"`
			}{
				{
					ID:             id2,
					MessageDataID:  id,
					SymmetricKey:   "",
					AssociationKey: "",
					Expiry:         time.Now(),
				},
			},
		},
	}

	jsonStr, _ := json.Marshal(d)
	req, _ := http.NewRequest("POST", ts.URL+"/api/v1/auth/message", 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)
		return
	}

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

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

}
