require('sbbsdefs.js', 'SYS_CLOSED');
var settings = load('modopts.js', 'web') || { web_directory: '../webv4' };
load(settings.web_directory + '/lib/init.js');
load(settings.web_lib + 'auth.js');
var request = require({}, settings.web_lib + 'request.js', 'request');

if (user.alias !== settings.guest) exit();
if (!settings.user_registration) exit();
if (system.settings&SYS_CLOSED) exit();

var MIN_ALIAS = 1,
	MIN_REALNAME = 3,
	MIN_NETMAIL = 6,
	MIN_LOCATION = 4,
	MIN_ADDRESS = 6,
	MIN_PHONE = 3;

var reply = {
	errors : [],
	userNumber : 0
};

var prepUser = {
	alias : '',
	handle : '',
	name : '',
	netmail : '',
	address : '',
	zipcode : '',
	location : '',
	phone : '',
	birthdate : '',
	gender : ' ',
	password : ''
};

function required(mask) {
	return (system.new_user_questions&mask);
}

function clean_param(param) {
	if (request.has_param(param)) return request.get_param(param).replace(/[\x00-\x19\x7F]/g, '');
	return "";
}

function in_range(n, min, max) {
	return n >= min && n <= max;
}

function valid_param(p, min, max) {
	if (!request.has_param(p)) return false;
	if (!in_range(clean_param(p).length, min, max)) return false;
	return true;
}

function is_dupe(field, str) {
	return system.matchuserdata(field, str) !== 0;
}

function newUser() {
	var usr = system.new_user(prepUser.alias);
	if (typeof usr === 'number') {
		reply.errors.push(locale.strings.api_register.error_failed);
		return;
	}
	log(LOG_INFO, format(locale.strings.api_register.log_success, usr.number));
	usr.security.password = prepUser.password;
	for (var property in prepUser) {
		if (property === 'alias' || property === 'password') continue;
		usr[property] = prepUser[property];
	}
	if (typeof settings.newuser_level == 'number' && settings.newuser_level >= 0 && settings.newuser_level <= 99) {
		usr.security.level = settings.newuser_level;
	}
	['flags1', 'flags2', 'flags3', 'flags4', 'exemptions', 'restrictions'].forEach(function (e) {
		const k = 'newuser_' + e;
		if (settings[k] && settings[k].search(/[^a-zA-Z]/) < 0) {
			usr.security[e] = '+' + settings[k];
		}
	});
	reply.userNumber = usr.number;
}

// See if the hidden form fields were filled
if (request.get_param('send-me-free-stuff') != '' || request.get_param('subscribe-to-newsletter') !== undefined) {
	log(LOG_WARNING, locale.strings.api_register.log_bot_attempt);
	exit();
}

if (system.newuser_password !== '' && (!request.has_param('newuser-password') || request.get_param('newuser-password') != system.newuser_password)) {
	reply.errors.push(locale.strings.api_register.error_bad_syspass);
}

 if (system.matchuser(clean_param('alias')) > 0) {
	reply.errors.push(locale.strings.api_register.error_alias_taken);
} else  if (!valid_param('alias', MIN_ALIAS, LEN_ALIAS) || !system.check_name(clean_param('alias'))) {
	reply.errors.push(locale.strings.api_register.error_invalid_alias);
} else {
	prepUser.alias = clean_param('alias');
	prepUser.handle = clean_param('alias');
}

if (!request.has_param('password1') || !request.has_param('password2') || clean_param('password1') != clean_param('password2')) {
	reply.errors.push(locale.strings.api_register.error_password_mismatch);
} else if (!in_range(clean_param('password1').length, system.min_password_length, system.max_password_length)) {
	reply.errors.push(format(locale.strings.api_register.error_password_length, system.min_password_length, system.max_password_length));
} else {
	prepUser.password = clean_param('password1');
}

if (valid_param('netmail', MIN_NETMAIL, LEN_NETMAIL)) {
	prepUser.netmail = clean_param('netmail');
} else if (!required(UQ_NONETMAIL)) {
	reply.errors.push(locale.strings.api_register.error_email_required);
}

if (valid_param('realname', MIN_REALNAME, LEN_NAME) && (!required(UQ_DUPREAL) || !is_dupe(U_NAME, clean_param('realname')))) {
	prepUser.name = clean_param('realname');
} else if (required(UQ_REALNAME)) {
	reply.errors.push(locale.strings.api_register.error_invalid_name);
}

// UQ_NOCOMMAS should be checked and acted on
if (valid_param('location', MIN_LOCATION, LEN_LOCATION)) {
	prepUser.location = clean_param('location');
} else if (required(UQ_LOCATION)) {
	reply.errors.push(locale.strings.api_register.error_invalid_location);
}

if (valid_param('address', MIN_ADDRESS, LEN_ADDRESS) && valid_param('zipcode', 3, LEN_ADDRESS)) {
	prepUser.address = clean_param('address');
	prepUser.zipcode = clean_param('zipcode');
} else if (required(UQ_ADDRESS)) {
	reply.errors.push(locale.strings.api_register.error_invalid_street_address);
}

// Validate?  Who cares?
if (valid_param('phone', MIN_PHONE, LEN_PHONE)) {
	prepUser.phone = clean_param('phone');
} else if (required(UQ_PHONE)) {
	reply.errors.push(locale.strings.api_register.error_invalid_phone);
}

if (valid_param('gender', 1, 1) && ['X', 'M', 'F', 'O'].indexOf(request.get_param('gender')) > -1) {
	prepUser.gender = clean_param('gender');
} else if (required(UQ_SEX)) {
	reply.errors.push(locale.strings.api_register.error_invalid_gender);
}

if (request.has_param('birth') && clean_param('birth').match(/^\d\d\/\d\d\/\d\d$/) !== null) {
	// Should really test for valid date (and date format per system config)
	prepUser.birthdate = clean_param('birth');
} else if (required(UQ_BIRTH)) {
	reply.errors.push(locale.strings.api_register.error_invalid_birthdate);
}

if (reply.errors.length < 1) newUser();

reply = JSON.stringify(reply);
http_reply.header['Content-Type'] = 'application/json';
http_reply.header['Content-Length'] = reply.length;
write(reply);

prepUser = undefined;
reply = undefined;