package anonym_del

import (
	"bytes"
	"net/http"
	"net/url"
	"os"
	"strings"
	"testing"

	"github.com/gofiber/fiber/v2"

	"git.p78su.freemyip.com/svi/gostore/pkg/mock/mock_service"
	"git.p78su.freemyip.com/svi/gostore/pkg/mock/mock_store"
	"git.p78su.freemyip.com/svi/gostore/pkg/mock/mock_web"
	"git.p78su.freemyip.com/svi/gostore/pkg/types"
)

type tester struct {
	t      *testing.T
	serv   *mock_service.MockService
	web    types.IServHttp
	router fiber.Router
	del    *AnonymDel
}

func TestAnonymDel(t *testing.T) {
	fnClear := func() {
		_ = os.RemoveAll("./store")
	}
	fnClear()
	defer fnClear()
	sf := &tester{
		t: t,
	}
	sf.create()
	sf._del()
	sf.post()
	// sf.close()
}

// пост-запрос на удаление ключа
func (sf *tester) post() {
	sf.t.Log("post")
	sf.postBad1()
	sf.postBad2()
	sf.postGood1()
	sf.postBad3()
}

// Удаление ключа при закрытом хранилище
func (sf *tester) postBad3() {
	sf.t.Log("postBad3")
	app := fiber.New()
	app.Post("/anonym/del", sf.del.post)
	formData := url.Values{
		"key": {"key"},
	}
	req, err := http.NewRequest("POST", "/anonym/del", strings.NewReader(formData.Encode()))
	if err != nil {
		sf.t.Fatalf("postBad3(): err=\n\t%v", err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	mock_store.IsBad_ = true
	resp, err := app.Test(req)
	if err != nil {
		sf.t.Fatalf("postBad3(): err=\n\t%v", err)
	}
	defer resp.Body.Close()
	// Здесь проблема с расположением шаблонов в другом месте
	// if resp.StatusCode != 200 {
	// 	sf.t.Fatalf("postBad3(): resp.Status=%v", resp.Status)
	// }
	mock_store.IsBad_ = false
}

func (sf *tester) postGood1() {
	sf.t.Log("postGood1")
	app := fiber.New()
	app.Post("/anonym/del", sf.del.post)
	formData := url.Values{
		"key": {"key"},
	}
	req, err := http.NewRequest("POST", "/anonym/del", strings.NewReader(formData.Encode()))
	if err != nil {
		sf.t.Fatalf("postGood1(): err=\n\t%v", err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	resp, err := app.Test(req)
	if err != nil {
		sf.t.Fatalf("postGood1(): err=\n\t%v", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		sf.t.Fatalf("postGood1(): resp.Status=%v", resp.Status)
	}
}

// Неправильная форма запроса на удаление (пустой ключ)
func (sf *tester) postBad2() {
	sf.t.Log("postBad2")
	app := fiber.New()
	app.Post("/anonym/del", sf.del.post)
	formData := url.Values{
		"key": {""},
	}
	req, err := http.NewRequest("POST", "/anonym/del", strings.NewReader(formData.Encode()))
	if err != nil {
		sf.t.Fatalf("postBad2(): err=\n\t%v", err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	resp, err := app.Test(req)
	if err != nil {
		sf.t.Fatalf("postBad2(): err=\n\t%v", err)
	}
	defer resp.Body.Close()
	// Проблема с расположением шаблонов для рендеринга
	// if resp.StatusCode != 200 {
	// 	sf.t.Fatalf("postBad2(): resp.Status=%v", resp.Status)
	// }
}

// Неправильная форма запроса на удаление
func (sf *tester) postBad1() {
	sf.t.Log("postBad1")
	app := fiber.New()
	app.Post("/anonym/del", sf.del.post)
	body := bytes.NewBuffer([]byte(``))
	req, err := http.NewRequest("POST", "/anonym/del", body)
	if err != nil {
		sf.t.Fatalf("postBad1(): err=\n\t%v", err)
	}
	resp, err := app.Test(req)
	if err != nil {
		sf.t.Fatalf("postBad1(): err=\n\t%v", err)
	}
	defer resp.Body.Close()
	// Проблема с расположением шаблонов для рендеринга
	// if resp.StatusCode != 200 {
	// 	sf.t.Fatalf("postBad1(): resp.Status=%v", resp.Status)
	// }
}

// Удаление ключа из хранилища
func (sf *tester) _del() {
	sf.t.Log("del")
	sf.delBad1()
	sf.delCheckKeyBad1()
	sf.delCheckKeyBad2()
	sf.delCheckKeyGood1()
}

// онлайн проверка ключа на допустимость
func (sf *tester) delCheckKeyGood1() {
	sf.t.Log("delCheckKeyGood1")
	app := fiber.New()
	app.Post("/anonym/del_check_key", sf.del.delCheckKey)
	formData := url.Values{
		"key": {"key"},
	}
	req, err := http.NewRequest("POST", "/anonym/del_check_key", strings.NewReader(formData.Encode()))
	if err != nil {
		sf.t.Fatalf("delCheckKeyGood1(): err=\n\t%v", err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	resp, err := app.Test(req)
	if err != nil {
		sf.t.Fatalf("delCheckKeyGood1(): err=\n\t%v", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		sf.t.Fatalf("delCheckKeyGood1(): resp.Status=%v", resp.Status)
	}
}

// онлайн проверка ключа на допустимость (ключ пустой)
func (sf *tester) delCheckKeyBad2() {
	sf.t.Log("delCheckKeyBad2")
	app := fiber.New()
	app.Post("/anonym/del_check_key", sf.del.delCheckKey)
	formData := url.Values{
		"key": {""},
	}
	req, err := http.NewRequest("POST", "/anonym/del_check_key", strings.NewReader(formData.Encode()))
	if err != nil {
		sf.t.Fatalf("delCheckKeyBad2(): err=\n\t%v", err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	resp, err := app.Test(req)
	if err != nil {
		sf.t.Fatalf("delCheckKeyBad2(): err=\n\t%v", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		sf.t.Fatalf("delCheckKeyBad2(): resp.Status=%v", resp.Status)
	}
}

// онлайн проверка ключа на допустимость (нет ключа в запросе)
func (sf *tester) delCheckKeyBad1() {
	sf.t.Log("delCheckKeyBad1")
	app := fiber.New()
	app.Post("/anonym/del_check_key", sf.del.delCheckKey)
	body := bytes.NewBuffer([]byte(``))
	req, err := http.NewRequest("POST", "/anonym/del_check_key", body)
	if err != nil {
		sf.t.Fatalf("delCheckKeyBad1(): err=\n\t%v", err)
	}
	resp, err := app.Test(req)
	if err != nil {
		sf.t.Fatalf("delCheckKeyBad1(): err=\n\t%v", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		sf.t.Fatalf("delCheckKeyBad1(): resp.Status=%v", resp.Status)
	}
}

// Нет ключа в запросе
func (sf *tester) delBad1() {
	sf.t.Log("delBad1")
	app := fiber.New()
	app.Get("/anonym/del", sf.del.get)
	req, err := http.NewRequest("GET", "/anonym/del", nil)
	if err != nil {
		sf.t.Fatalf("delBad1(): err=\n\t%v", err)
	}
	resp, err := app.Test(req)
	if err != nil {
		sf.t.Fatalf("delBad1(): err=\n\t%v", err)
	}
	defer resp.Body.Close()
	// Здесь проблема с расположением шаблонов в другом месте
	// if resp.StatusCode != 200 {
	// 	sf.t.Fatalf("delBad1(): resp.Status=%v", resp.Status)
	// }
}

// Создание удалятора анонимных ключей
func (sf *tester) create() {
	sf.t.Log("create")
	sf.createBad1()
	sf.createBad2()
	sf.createGood1()
}

func (sf *tester) createGood1() {
	sf.t.Log("createGood1")
	sf.router = sf.web.FiberApp().Group("/anonym")
	var err error
	sf.del, err = NewAnonymDel(sf.web, sf.router)
	if err != nil {
		sf.t.Fatalf("createGood1(): err=\n\t%v", err)
	}
	if sf.del == nil {
		sf.t.Fatalf("createGood1(): anonDel==nil")
	}
}

// Нет анонимного роутера
func (sf *tester) createBad2() {
	sf.t.Log("createBad2")
	var err error
	sf.serv = mock_service.NewMockService()
	sf.serv.Store_, err = mock_store.NewMockStore(sf.serv)
	if err != nil {
		sf.t.Fatalf("postBad2(): err=\n\t%v", err)
	}
	sf.web, err = mock_web.NewMockWeb(sf.serv)
	if err != nil {
		sf.t.Fatalf("createBad2(): err=\n\t%v", err)
	}
	anonDel, err := NewAnonymDel(sf.web, nil)
	if err == nil {
		sf.t.Fatalf("createBad2(): err==nil")
	}
	if anonDel != nil {
		sf.t.Fatalf("createBad2(): anonDel!=nil")
	}
}

// Нет объекта веб-сервера
func (sf *tester) createBad1() {
	sf.t.Log("createBad1")
	store, err := NewAnonymDel(nil, nil)
	if err == nil {
		sf.t.Fatalf("createBad1(): err==nil")
	}
	if store != nil {
		sf.t.Fatalf("createBad1(): store!=nil")
	}
}
