/*
 * Copyright (c) 2005-2006 William Pitcock, et al.
 * Rights to this code are as documented in doc/LICENSE.
 *
 * Sets usercloak metadata on register.
 */

#include "atheme-compat.h"

/* allow us-ascii letters, digits and the following characters */
#define VALID_SPECIALS "-"

static int counter = 0;

static void
user_add_host(myuser_t *mu)
{
	int maxlen1, i;
	char newhost[COMPAT_HOSTLEN + 1];
	const char *p;
	bool invalidchar = false;

	maxlen1 = COMPAT_HOSTLEN - 1 - strlen(me.hidehostsuffix);
	if (maxlen1 < 9)
		return;
	p = entity(mu)->name;
	i = 0;
	while (i < maxlen1 && *p != '\0')
	{
		if (isalnum((unsigned char)*p) || strchr(VALID_SPECIALS, *p))
			newhost[i++] = *p;
		else
			invalidchar = true;
		p++;
	}
	if (invalidchar || *p != '\0')
	{
		if (i > maxlen1 - 6)
			i = maxlen1 - 6;
		snprintf(newhost + i, sizeof newhost - i, "-%05d", counter);
		counter++;
		if (counter >= 100000)
			counter = 0;
		if (nicksvs.me != NULL)
		{
			myuser_notice(nicksvs.nick, mu, "Your account name cannot be used in a vhost directly. To ensure uniqueness, a number was added.");
			myuser_notice(nicksvs.nick, mu, "To avoid this, register an account name containing only letters, digits and %s.", VALID_SPECIALS);
			if (!nicksvs.no_nick_ownership && command_find(nicksvs.me->commands, "GROUP"))
				myuser_notice(nicksvs.nick, mu, "If you drop %s you can group it to your new account.", entity(mu)->name);
		}
	}
	else
		newhost[i] = '\0';
	mowgli_strlcat(newhost, ".", sizeof newhost);
	mowgli_strlcat(newhost, me.hidehostsuffix, sizeof newhost);

	metadata_add(mu, "private:usercloak", newhost);
}

static void
handle_verify_register(hook_user_req_t *req)
{
	myuser_t *mu = req->mu;
	mowgli_node_t *n;
	user_t *u;

	if (me.hidehostsuffix == NULL)
		return;

	user_add_host(mu);

	MOWGLI_ITER_FOREACH(n, mu->logins.head)
	{
		u = n->data;
		hook_call_user_identify(u); /* XXX */
	}
}

static void
hook_user_identify(user_t *u)
{
	/* if they have an existing cloak, don't do anything */
	if ((metadata_find(u->myuser, "private:usercloak")) || (me.hidehostsuffix == NULL))
		return;

	/* they do not, add one. */
	user_add_host(u->myuser);
}

static void
mod_init(module_t *const restrict m)
{
	hook_add_event("user_verify_register");
	hook_add_user_verify_register(handle_verify_register);
	hook_add_event("user_identify");
	hook_add_user_identify(hook_user_identify);
	counter = (CURRTIME << 8) % 100000;
	if (counter < 0)
		counter += 100000;
}

static void
mod_deinit(const module_unload_intent_t intent)
{
	hook_del_user_verify_register(handle_verify_register);
	hook_del_user_identify(hook_user_identify);
}

SIMPLE_DECLARE_MODULE_V1("contrib/gen_vhostonreg", MODULE_UNLOAD_CAPABILITY_OK)
