package Tests

import (
	"encoding/base64"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/cookiejar"
	"net/http/httptest"
	"net/url"
	"time"

	"git.tovijaeschke.xyz/tovi/Capsule/Backend/Api"
	"git.tovijaeschke.xyz/tovi/Capsule/Backend/Api/Auth"
	"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database"
	"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder"
	"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models"

	"github.com/gorilla/mux"
)

func InitTestCreateUser(username string) (Models.User, error) {
	userKey, err := Seeder.GenerateAesKey()
	if err != nil {
		return Models.User{}, err
	}
	pubKey := Seeder.GetPubKey()

	p, _ := Auth.HashPassword("password")

	u := Models.User{
		Username:             username,
		Password:             p,
		AsymmetricPublicKey:  Seeder.PublicKey,
		AsymmetricPrivateKey: Seeder.EncryptedPrivateKey,
		SymmetricKey: base64.StdEncoding.EncodeToString(
			Seeder.EncryptWithPublicKey(userKey.Key, pubKey),
		),
	}

	err = Database.CreateUser(&u)
	return u, err
}

// InitTestEnv initializes the test environment
// client is used for making authenticated requests
// ts is the testing server
// err, in case it fails ¯\_(ツ)_/¯
func InitTestEnv() (*http.Client, *httptest.Server, error) {
	log.SetOutput(ioutil.Discard)
	Database.InitTest()

	r := mux.NewRouter()
	Api.InitAPIEndpoints(r)
	ts := httptest.NewServer(r)

	u, err := InitTestCreateUser("test")
	if err != nil {
		return http.DefaultClient, ts, err
	}

	session := Models.Session{
		UserID: u.ID,
		Expiry: time.Now().Add(12 * time.Hour),
	}

	err = Database.CreateSession(&session)
	if err != nil {
		return http.DefaultClient, ts, err
	}

	jar, err := cookiejar.New(nil)

	url, _ := url.Parse(ts.URL)

	jar.SetCookies(
		url,
		[]*http.Cookie{
			{
				Name:   "session_token",
				Value:  session.ID.String(),
				MaxAge: 300,
			},
		},
	)

	client := &http.Client{
		Jar: jar,
	}

	return client, ts, err
}
