package server

import (
	"context"
	"encoding/json"

	"git.pyer.club/kingecg/goemitter"
	"git.pyer.club/kingecg/gotunnelserver/util"
	"github.com/gorilla/websocket"
)

type Session struct {
	Id     string
	conn   *websocket.Conn
	ctx    context.Context
	cancel context.CancelFunc
	*goemitter.EventEmitter
}

type Command struct {
	Type    int               `json:"type"`
	Payload map[string]string `json:"payload"`
}

func (s *Session) Send(cmd *Command) (err error) {
	return s.conn.WriteJSON(cmd)
}
func (s *Session) Close() {
	s.conn.Close()
}

func (s *Session) Start() {
	s.ctx, s.cancel = context.WithCancel(context.Background())
	go func() {
		defer s.conn.Close()
		for {
			var cmd Command
			err := s.conn.ReadJSON(&cmd)
			if err != nil {
				return
			}
			if cmd.Type == util.NewConnection {
				s.Emit("NewConnection", cmd.Payload)
			}
			select {
			case <-s.ctx.Done():
				return
			default:
				continue
			}
		}
	}()

}

func (s *Session) Stop() {
	s.cancel()
}

func NewSession(conn *websocket.Conn) *Session {
	return &Session{
		conn:         conn,
		Id:           util.GenRandomstring(16),
		EventEmitter: goemitter.NewEmitter(),
	}
}

func NewCommand(t int, p map[string]string) *Command {
	return &Command{
		Type:    t,
		Payload: p,
	}
}

func NcmdSession(sessionId string) *Command {
	return NewCommand(util.NewSession, map[string]string{"sessionId": sessionId})
}

func NewErrorResponse(err string, cmd *Command) *Command {
	payload := map[string]string{
		"error": err,
		// "originalcmd": strconv.Itoa(cmd.Type),
	}
	if cmd != nil {

		originalCmd, _ := json.Marshal(cmd)
		payload["originalcmd"] = string(originalCmd)

	}

	return NewCommand(util.ErrorCmd, payload)
}

func NcmdConnectionInited(sessionId string) *Command {
	return NewCommand(util.ConnectInited, map[string]string{"sessionId": sessionId})
}

func NcmdConnectionReady(sessionId string) *Command {
	return NewCommand(util.ConnectionReady, map[string]string{"sessionId": sessionId})
}
