#!/usr/local/bin/lua54
-- Prosody IM
-- Copyright (C) 2008-2010 Matthew Wild
-- Copyright (C) 2008-2010 Waqas Hussain
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--

-- prosody - main executable for Prosody XMPP server

-- Will be modified by configure script if run --

CFG_SOURCEDIR='/usr/local/lib/prosody';
CFG_CONFIGDIR='/etc/prosody';
CFG_PLUGINDIR='/usr/local/lib/prosody/modules/';
CFG_DATADIR='/var/prosody';

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

-- Check before first require, to preempt the probable failure
if _VERSION < "Lua 5.2" then
	io.stderr:write("Prosody is no longer compatible with Lua 5.1\n")
	io.stderr:write("See https://prosody.im/doc/depends#lua for more information\n")
	return os.exit(1);
end

-- Tell Lua where to find our libraries
-- and ensure that resources in the current directory are not picked up by accident
do
	-- Installed instance
	local function is_relative(path)
		local path_sep = package.config:sub(1,1);
		return ((path_sep == "/" and path:sub(1,1) ~= "/")
			or (path_sep == "\\" and (path:sub(1,1) ~= "/" and path:sub(2,3) ~= ":\\")))
	end
	local function filter_relative_paths(path)
		if is_relative(path) then return ""; end
	end
	local function sanitise_paths(paths)
		return (paths:gsub("[^;]+;?", filter_relative_paths):gsub(";;+", ";"));
	end
	package.path = (CFG_SOURCEDIR or ".") .. "/?.lua;" .. sanitise_paths(package.path);
	package.cpath = (CFG_SOURCEDIR or ".") .. "/?.so;" .. sanitise_paths(package.cpath);

	if pcall(dofile, (CFG_SOURCEDIR or ".") .. "/loader.lua") then
		package.loaded["prosody.loader"] = true;
	else
		require "prosody.loader";
	end
end

-- Substitute ~ with path to home directory in data path
if CFG_DATADIR then
	if os.getenv("HOME") then
		CFG_DATADIR = CFG_DATADIR:gsub("^~", os.getenv("HOME"));
	end
end


local startup = require "prosody.util.startup";
local async = require "prosody.util.async";

-- Note: it's important that this thread is not GC'd, as some C libraries
-- that are initialized here store a pointer to it ( :/ ).
local thread = async.runner();

thread:run(startup.prosody);

prosody.main_thread = thread;

local function loop()
	-- Error handler for errors that make it this far
	local function catch_uncaught_error(err)
		if type(err) == "string" and err:match("interrupted!$") then
			return "quitting";
		end

		prosody.log("error", "Top-level error, please report:\n%s", tostring(err));
		local traceback = debug.traceback("", 2);
		if traceback then
			prosody.log("error", "%s", traceback);
		end

		prosody.events.fire_event("very-bad-error", {error = err, traceback = traceback});
	end

	local sleep = require"socket".sleep;
	local server = require "prosody.net.server";

	while select(2, xpcall(server.loop, catch_uncaught_error)) ~= "quitting" do
		sleep(0.2);
	end
end

loop();

startup.exit();
