package handlers_test

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"testing"

	"otaupdate/handlers"

	"github.com/fiskerinc/cloud-services/pkg/httphandlers"
	"github.com/fiskerinc/cloud-services/pkg/testhelper"
)

const headerContentType = "Content-Type"

var swaggerHandler http.HandlerFunc

func init() {
	handlers.InitSwaggerDoc()

	swaggerHandler = httphandlers.GetSwaggerHandler()
}

func TestHandleSwaggerRedirect(t *testing.T) {
	req, _ := http.NewRequest("GET", "http://example.com/api", nil)
	req.RequestURI = req.URL.Path
	recorder := httptest.NewRecorder()

	swaggerHandler(recorder, req)

	validateSwaggerRedirect(t, recorder)
}

func TestHandleSwagger(t *testing.T) {
	req, _ := http.NewRequest("GET", "http://example.com/api/", nil)
	req.RequestURI = req.URL.Path
	recorder := httptest.NewRecorder()

	swaggerHandler(recorder, req)

	validateSwaggerRedirect(t, recorder)
}

func TestHandleSwaggerJSON(t *testing.T) {
	contentType := "application/json; charset=utf-8"
	req, _ := http.NewRequest("GET", "http://example.com/api/doc.json", nil)
	req.RequestURI = req.URL.Path
	recorder := httptest.NewRecorder()

	swaggerHandler(recorder, req)
	headers := recorder.Result().Header

	if headers.Get(headerContentType) != contentType {
		t.Errorf(testhelper.TestErrorTemplate, headerContentType, contentType, headers.Get(headerContentType))
	}

	var data map[string]interface{}

	err := json.Unmarshal(recorder.Body.Bytes(), &data)
	if err != nil {
		t.Error(err)
	}
}

func TestHandleSwaggerHTML(t *testing.T) {
	contentType := "text/html; charset=utf-8"
	htmlTitle := "<title>Swagger UI</title>"
	req, _ := http.NewRequest("GET", "http://example.com/api/index.html", nil)
	req.RequestURI = req.URL.Path
	recorder := httptest.NewRecorder()

	swaggerHandler(recorder, req)
	headers := recorder.Result().Header

	if headers.Get(headerContentType) != contentType {
		t.Errorf(testhelper.TestErrorTemplate, headerContentType, contentType, headers.Get(headerContentType))
	}

	if !strings.Contains(recorder.Body.String(), htmlTitle) {
		t.Errorf(testhelper.TestErrorTemplate, "HTML", htmlTitle, recorder.Body.String())
	}
}

func validateSwaggerRedirect(t *testing.T, recorder *httptest.ResponseRecorder) {
	if recorder.Code != http.StatusMovedPermanently {
		t.Errorf(testhelper.TestErrorTemplate, "Status code", http.StatusMovedPermanently, recorder.Code)
	}

	u, err := url.Parse(recorder.Header().Get("location"))
	if err != nil {
		t.Error(err)
	}

	if u.Path != "/api/index.html" {
		t.Errorf(testhelper.TestErrorTemplate, "Path", "/api/index.html", u.Path)
	}
}
