//Allow user of @ in in require calls. Config in package.json
require('module-alias/register')

let Auth = require('@helpers/Auth')

const express = require('express')
const app = express()
const port = 3000

var http = require('http').createServer(app);
var io = require('socket.io')(http, {
	path:'/socket'
});

// Make io accessible to our router
app.use(function(req,res,next){
	req.io = io;
	next();
});

io.on('connection', function(socket){

	// console.log('New user ', socket.id)

	socket.on('join_room', roomId => {
		// console.log('Join room ', roomId)
		socket.join(roomId)

		const usersInRoom = io.sockets.adapter.rooms[roomId]
		if(usersInRoom){
			// console.log('Users in room', usersInRoom.length)
			io.to(roomId).emit('update_user_count', usersInRoom.length)
		}
	})

	socket.on('leave_room', roomId => {
		socket.leave(roomId)
		// console.log('User Left room')

		const usersInRoom = io.sockets.adapter.rooms[roomId]
		if(usersInRoom){
			// console.log('Users in room', usersInRoom.length)
			io.to(roomId).emit('update_user_count', usersInRoom.length)
		}
		
	})

	socket.on('note_diff', data => {

		//Each user joins a room when they open the app.
		io.in(data.id).clients((error, clients) => {
			if (error) throw error;
			//Go through each client in note room and send them the diff
			clients.forEach(socketId => {
				if(socketId != socket.id){
					io.to(socketId).emit('incoming_diff', data.diff)
				}
			})

		});

	})

	socket.on('disconnect', function(){
		// console.log('user disconnected');
	});
});


http.listen(3001, function(){
	console.log('socket.io liseting on port 3001');
});

//Enable json body parsing in requests. Allows me to post data in ajax calls
app.use(express.json({limit: '2mb'}))


//Prefix defied by route in nginx config
const prefix = '/api'

//App Auth, all requests will come in with a token, decode the token and set global var
app.use(function(req, res, next){
	//auth token set by axios in headers
	let token = req.headers.authorizationtoken
	if(token && token != null && typeof token === 'string'){
		Auth.decodeToken(token)
		.then(userData => {
			req.headers.userId = userData.id //Update headers for the rest of the application
			next()
		}).catch(error => {

			res.statusMessage = error //Throw 400 error if token is bad
		    res.status(400).end()
		})
	} else {
		next() //No token. Move along.
	}
})

//Test 
app.get(prefix, (req, res) => res.send('The api is running'))

//Serve up uploaded files
app.use(prefix+'/static', express.static( __dirname+'/../staticFiles' ))

//Public routes
var public = require('@routes/publicController')
app.use(prefix+'/public', public)

//user endpoint
var user = require('@routes/userController')
app.use(prefix+'/user', user)

//notes endpoint
var notes = require('@routes/noteController')
app.use(prefix+'/note', notes)

//tags endpoint
var tags = require('@routes/tagController')
app.use(prefix+'/tag', tags)

//notes endpoint
var attachment = require('@routes/attachmentController')
app.use(prefix+'/attachment', attachment)

//quick notes endpoint
var quickNote = require('@routes/quicknoteController')
app.use(prefix+'/quick-note', quickNote)

//Output running status
app.listen(port, () => console.log(`Listening on port ${port}!`))