--[==[

	Canvas-UI-based Application Server.
	Written by Cosmin Apreutesei. Public Domain.

LOADS

	canvas-ui

USAGE

	local myapp = require('xapp')(...)
	....
	return myapp:run(...)

PUBLISHES

	myapp.schema

USES

	function myapp:install() end

CONFIG

	ignore_interrupts
	host
	dev_email

]==]

--NOTE: www_dirs must be set before any jsfile(), cssfile(), htmlfile() calls!
require'glue'
config('www_dirs', 'www;sdk/www;sdk/canvas-ui/www')

require'daemon'
require'webb_spa'
require'xrowset'
require'schema'

js[[
document.addEventListener('DOMContentLoaded', function init_all() {
	init_action()
})
]]

jsfile[[
ui.js
ui_validation.js
ui_nav.js
ui_grid.js
adapter.js
webrtc.js
]]

require'xauth'

local function xapp(...)

	local app = daemon(...)

	function app:run_server()
		app.server = webb_http_server()
		start(config('ignore_interrupts', true))
	end

	function logging.rpc:close_all_sockets()
		app.server:close_all_sockets()
		close_all_dbs()
	end

	app.before = before
	app.after = after

	function app:run_cmd(cmd_name, cmd_run, cmd_opt, ...)
		local exit_code
		if cmd_name == 'run' then
			exit_code = cmd_run(cmd_name, cmd_opt, ...)
		else
			exit_code = run(function(...)
				local ok, err = pcall(cmd_run, cmd_name, cmd_opt, ...)
				if not ok then --check500, assert, etc.
					log('ERROR', 'xapp', 'run', '%s', err)
					return 1
				end
				return err --exit_code
			end, ...)
		end
		if logging.debug then --show any leaks.
			logging.printlive()
		end
		return exit_code
	end

	config('main_module', function()
		checkfound(action(unpack(args())))
	end)

	app.schema = schema()

	app.schema.env.null = null
	app.schema.env.Sf = Sf

	app.schema:import'schema_std'
	app.schema:import'webb_auth'

	sqlpps.mysql    .define_symbol('current_timestamp', app.schema.env.current_timestamp)
	sqlpps.tarantool.define_symbol('current_timestamp', app.schema.env.current_timestamp)

	config('db_schema', app.schema)

	if config('multilang', true) then
		require'xlang'
	end

	cmd('install [forealz]', 'Install or migrate the app', function(opt, doit)
		create_db()
		local dry = doit ~= 'forealz'
		db():sync_schema(app.schema, {dry = dry})
		if not dry then
			insert_or_update_row('tenant', {
				tenant = 1,
				name = 'default',
				host = config'host',
			})
			if config'dev_email' then
				usr_create_or_update{
					tenant = 1,
					email = config'dev_email',
					roles = 'dev admin',
				}
			end
			if app.install then
				app:install()
			end
		end
		say'Install done.'
	end)

	return app
end

return xapp
