package itypes

import (
	"sync"

	"github.com/civet148/log"
	"github.com/gorilla/websocket"
)

// The message types are defined in RFC 6455, section 11.8.
const (
	// TextMessage denotes a text data message. The text message payload is
	// interpreted as UTF-8 encoded text data.
	TextMessage = 1

	// BinaryMessage denotes a binary data message.
	BinaryMessage = 2

	// CloseMessage denotes a close control message. The optional message
	// payload contains a numeric code and text. Use the FormatCloseMessage
	// function to format a close message payload.
	CloseMessage = 8

	// PingMessage denotes a ping control message. The optional message payload
	// is UTF-8 encoded text.
	PingMessage = 9

	// PongMessage denotes a pong control message. The optional message payload
	// is UTF-8 encoded text.
	PongMessage = 10
)

type WebSocket struct {
	outlocker sync.RWMutex    //外部锁
	inlocker  sync.RWMutex    //内部锁
	msgType   int             //消息类型
	ws        *websocket.Conn //websocket连接
	id        string          //会话ID
}

func NewWebSocket(conn *websocket.Conn, id string) (*WebSocket, error) {
	if conn == nil {
		return nil, log.Errorf("websocket connection is nil")
	}

	return &WebSocket{
		ws:      conn,
		id:      id,
		msgType: TextMessage,
	}, nil
}

func (m *WebSocket) Lock() {
	m.outlocker.Lock()
}

func (m *WebSocket) Unlock() {
	m.outlocker.Unlock()
}

func (m *WebSocket) ReadMessage() ([]byte, error) {
	typ, data, err := m.ws.ReadMessage()
	m.msgType = typ
	return data, err
}

func (m *WebSocket) WriteMessage(data []byte) error {
	m.inlocker.Lock()
	defer m.inlocker.Unlock()
	return m.ws.WriteMessage(m.msgType, data)
}

func (m *WebSocket) Close() error {
	return m.ws.Close()
}

func (m *WebSocket) Id() string {
	return m.id
}

func (m *WebSocket) MsgType() int {
	return m.msgType
}
