package websocket

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/fiskerinc/cloud-services/pkg/testhelper"

	"github.com/gobwas/ws"
	"github.com/gobwas/ws/wsutil"
)

func TestSessionMobile(t *testing.T) {
	ws, _ := net.Pipe()
	s := SessionMobile{
		Session: &Session{
			Websocket: ws,
		},
	}

	if fmt.Sprintf("%T", s) != "websocket.SessionMobile" {
		t.Errorf(testhelper.TestErrorTemplate, "TestSessionMobile", "websocket.SessionMobile", fmt.Sprintf("%T", s))
	}
}

func TestNewSessionMobile(t *testing.T) {
	createNewSession := func(w http.ResponseWriter, r *http.Request) {
		s, err := NewMobileSession(w, r, "1.2.3.4")
		if err != nil {
			t.Errorf(testhelper.TestErrorTemplate, "TestNewSessionMobile", nil, err)
		}
		defer s.Close()

		if fmt.Sprintf("%T", s) != "*websocket.SessionMobile" {
			t.Errorf(testhelper.TestErrorTemplate, "TestNewSessionMobile", "*websocket.SessionMobile", fmt.Sprintf("%T", s))
		}
	}

	server := httptest.NewServer(http.HandlerFunc(createNewSession))
	defer server.Close()

	conn := createMockWebsocketClient(server.URL, "")
	defer conn.Close()
}

func TestSessionMobileAuthenticate(t *testing.T) {
	userAgent := "Mobile 1.2.3.4"

	createNewSession := func(w http.ResponseWriter, r *http.Request) {
		s, err := NewInsecureSession(w, r)
		if err != nil {
			t.Errorf(testhelper.TestErrorTemplate, "TestSessionMobileAuthenticate", nil, err)
		}
		defer s.Close()

		err = s.Authenticate()
		if err == nil {
			t.Errorf(testhelper.TestErrorTemplate, "TestSessionMobileAuthenticate", "error", nil)
		}
	}

	server := httptest.NewServer(http.HandlerFunc(createNewSession))
	defer server.Close()

	conn := createMockWebsocketClient(server.URL, userAgent)
	defer conn.Close()

	am := common.MobileSessionMessage{
		Handler: "verify",
		Data: common.MobileSessionData{
			Token: "validtoken",
		},
	}

	msg, err := json.Marshal(am)
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "TestSessionMobileAuthenticate", nil, err)
	}

	wsutil.WriteClientMessage(conn, ws.OpText, msg)
}
