// This handler receive the incoming connections from the storages
func (m *Bridger) serverReceptioner(storageConn *ws.MyConn) bool {

	// Get the user Id
	id := context.Get(storageConn.HttpRequest, "userId").(int64)

	// Check if another storage is already connected
	_, connected := m.storages[id]

	storageConn.SendEvent(ws.Event{
		Name: "initialization",
		Data: map[string]bool{
			"success": !connected,
		},
	})

	if connected {
		return false
	}

	// Create the storage manager
	storage := Storage{

		// Ws connection to the storage
		ws: storageConn,

		// Lock for the clients array
		clientLock: &sync.Mutex{},

		// Map of the clients connected to this sotrage
		clients: make(map[Client]bool),

		// Shutdow channel
		shutdown: make(chan (bool)),
	}

	storageConn.SetListener(func(event ws.Event) {

		if event.Name == "_error" {
			// Lock the array
			storage.clientLock.Lock()

			// Notify this error to all the clients of this storage
			for client := range storage.clients {
				client.ws.SendEvent(ws.Event{
					Name: "storageInfo",
					Data: map[string]bool{"connected": false},
				})
				// TODO: add a function to close the client, not close the
				// raw socket!
				client.ws.Close()
			}

			// Unlock the array
			storage.clientLock.Unlock()

			// And then remove the storage from the storages map
			delete(m.storages, id)

			return
		}

		// Repeat this event to all the clients
		for client, _ := range storage.clients {

			client.ws.SendEvent(event)
		}
	})

	// Once that i'm sure of the hidentity of the server, let's add
	// to the servers map.
	m.storages[id] = &storage

	// Return a nil because no informations need to be attached to this connection
	// (i dunno why i have created this info, and probably i'll remove the connection info
	// soon), and a true that means that this conenction is a good ione and shouldn't be
	// closed
	return true
}
// This method is called when a new ws connection is made by a client.
// This method check if the user is authorized and create a new struct that describe
// the user.
func (m *Bridger) clientReceptioner(clientConn *ws.MyConn) bool {

	// Get the user Id
	id := context.Get(clientConn.HttpRequest, "userId").(int64)

	// Check if the storage of this user is conencted
	storage, connected := m.storages[id]

	// Send the storage connection state
	clientConn.SendEvent(ws.Event{
		Name: "storageInfo",
		Data: map[string]bool{
			"connected": connected,
		},
	})

	// If the storage is not connected, close the connections of this client
	if !connected {

		// Return false, that means close the ws connection
		return false
	}

	// Create a new client object
	client := Client{
		ws: clientConn,
	}

	// Lock the array
	storage.clientLock.Lock()

	// Add the client to the map of clients of this storage
	storage.clients[client] = true

	// Unlock the array
	storage.clientLock.Unlock()

	clientConn.SetListener(func(event ws.Event) {

		if event.Name == "_error" {

			// In this case the client is disconnected
			fmt.Println("Client disconnected")

			// So remove it from the clients array in the storage struct

			// Lock the mutex of the map
			storage.clientLock.Lock()

			// Remove from the array
			delete(storage.clients, client)

			// Unlock the mutex of the map
			storage.clientLock.Unlock()

			return
		}

		if event.QueryId != "" {

			storage.ws.MakeAsyncQuery(event, func(data interface{}) {

				response := ws.Event{
					QueryId: event.QueryId,
					Name:    "queryResponse",
					Data:    data,
				}

				clientConn.SendEvent(response)
			})

			return
		}

		// Redirect the event to the storage
		err := storage.ws.SendEvent(event)

		if err != nil {

			// TODO: handle this kind of error
			fmt.Println("Error proxying message to storage")
		}
	})

	// keep the connection and don't add any info
	return true
}