/*
 *  Chrome OS Metrics - collect and record metrics data through UMA
 *
 *  This file initially created by Google, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#if 0
#define CONFIG_PSB_SUPPORT		/* enable Public Safety Band support */
#endif

#include <ctype.h>
#include <stdlib.h>
#include <string.h>

#include <metrics/c_metrics_library.h>

#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/assert.h>
#include <connman/plugin.h>
#include <connman/notifier.h>
#include <connman/network.h>
#include <connman/service.h>
#include <connman/log.h>

#define	_DBG_METRICS(fmt, arg...)	DBG(DBG_METRICS, fmt, ## arg)

#define	METRIC_NAME_LEN	80		/* max size of a constructed name */

static CMetricsLibrary lib = NULL;

const char *kMetricNetworkTimeToDropName = "Network.TimeToDrop";
const int kMetricNetworkTimeToDropMin = 1;
const int kMetricNetworkTimeToDropMax = 8 * 60 * 60;	/* 8 hours */
const int kMetricNetworkTimeToDropBuckets = 50;

const char *kMetricNetworkTimeOnlineName = "Network.%c%s.TimeOnline";
const int kMetricNetworkTimeOnlineMin = 1;
const int kMetricNetworkTimeOnlineMax = 8 * 60 * 60;	/* 8 hours */
const int kMetricNetworkTimeOnlineBuckets = 50;

const char *kMetricNetworkTimeToJoinName = "Network.%c%s.TimeToJoin";
const char *kMetricNetworkTimeToConfigName = "Network.%c%s.TimeToConfig";
const char *kMetricNetworkTimeToOnline = "Network.%c%s.TimeToOnline";
const char *kMetricNetworkTimeToPortal = "Network.%c%s.TimeToPortal";
const char *kMetricNetworkTimeResumeToReady = "Network.%c%s.TimeResumeToReady";

const char *kMetricNetworkServiceErrors = "Network.ServiceErrors";
const int kMetricNetworkServiceErrorsMax = CONNMAN_SERVICE_ERROR_MAX;

const char *kMetricNetworkSecurity = "Network.%c%s.Security";
const int kMetricNetworkSecurityMax = CONNMAN_SERVICE_SECURITY_MAX;

const char *kMetricNetworkAuthMode = "Network.%c%s.AuthMode";
enum connman_authmode {
	CONNMAN_AUTHMODE_UNKNOWN = 0,

	CONNMAN_AUTHMODE_EAP_AKA = 1,
	CONNMAN_AUTHMODE_EAP_FAST = 2,
	CONNMAN_AUTHMODE_EAP_GPSK = 3,
	CONNMAN_AUTHMODE_EAP_GTC = 4,
	CONNMAN_AUTHMODE_EAP_IKEV2 = 5,
	CONNMAN_AUTHMODE_EAP_LEAP = 6,
	CONNMAN_AUTHMODE_EAP_MD5 = 7,
	CONNMAN_AUTHMODE_EAP_MSCHAPV2 = 8,
	CONNMAN_AUTHMODE_EAP_OTP = 9,
	CONNMAN_AUTHMODE_EAP_PAX = 10,
	CONNMAN_AUTHMODE_EAP_PEAP = 11,
	CONNMAN_AUTHMODE_EAP_PSK = 12,
	CONNMAN_AUTHMODE_EAP_SAKE = 13,
	CONNMAN_AUTHMODE_EAP_SIM = 14,
	CONNMAN_AUTHMODE_EAP_TLS = 15,
	CONNMAN_AUTHMODE_EAP_TNC = 16,
	CONNMAN_AUTHMODE_EAP_TTLS = 17,

	CONNMAN_AUTHMODE_MAX,
};
const int kMetricNetworkAuthModeMax = CONNMAN_AUTHMODE_MAX;

enum connman_channel {
	CONNMAN_CHANNEL_UNDEF = 0,
	CONNMAN_CHANNEL_2412 = 1,
	CONNMAN_CHANNEL_2417 = 2,
	CONNMAN_CHANNEL_2422 = 3,
	CONNMAN_CHANNEL_2427 = 4,
	CONNMAN_CHANNEL_2432 = 5,
	CONNMAN_CHANNEL_2437 = 6,
	CONNMAN_CHANNEL_2442 = 7,
	CONNMAN_CHANNEL_2447 = 8,
	CONNMAN_CHANNEL_2452 = 9,
	CONNMAN_CHANNEL_2457 = 10,
	CONNMAN_CHANNEL_2462 = 11,
	CONNMAN_CHANNEL_2467 = 12,
	CONNMAN_CHANNEL_2472 = 13,
	CONNMAN_CHANNEL_2484 = 14,

	CONNMAN_CHANNEL_5180 = 15,
	CONNMAN_CHANNEL_5200 = 16,
	CONNMAN_CHANNEL_5220 = 17,
	CONNMAN_CHANNEL_5240 = 18,
	CONNMAN_CHANNEL_5260 = 19,
	CONNMAN_CHANNEL_5280 = 20,
	CONNMAN_CHANNEL_5300 = 21,
	CONNMAN_CHANNEL_5320 = 22,

	CONNMAN_CHANNEL_5500 = 23,
	CONNMAN_CHANNEL_5520 = 24,
	CONNMAN_CHANNEL_5540 = 25,
	CONNMAN_CHANNEL_5560 = 26,
	CONNMAN_CHANNEL_5580 = 27,
	CONNMAN_CHANNEL_5600 = 28,
	CONNMAN_CHANNEL_5620 = 29,
	CONNMAN_CHANNEL_5640 = 30,
	CONNMAN_CHANNEL_5660 = 31,
	CONNMAN_CHANNEL_5680 = 32,
	CONNMAN_CHANNEL_5700 = 33,

	CONNMAN_CHANNEL_5745 = 34,
	CONNMAN_CHANNEL_5765 = 35,
	CONNMAN_CHANNEL_5785 = 36,
	CONNMAN_CHANNEL_5805 = 37,
	CONNMAN_CHANNEL_5825 = 38,

	CONNMAN_CHANNEL_5170 = 39,
	CONNMAN_CHANNEL_5190 = 40,
	CONNMAN_CHANNEL_5210 = 41,
	CONNMAN_CHANNEL_5230 = 42,

	/* NB: ignore old 11b bands 2312..2372 and 2512..2532 */
	/* NB: ignore regulated bands 4920..4980 and 5020..5160 */

#ifdef CONFIG_PSB_SUPPORT
	CONNMAN_CHANNEL_PSB_4940 = 43,	/* NB: PSB center freq's are +.5MHz */
	CONNMAN_CHANNEL_PSB_4941 = 44,
	CONNMAN_CHANNEL_PSB_4942 = 45,
	CONNMAN_CHANNEL_PSB_4943 = 46,
	CONNMAN_CHANNEL_PSB_4944 = 47,
	CONNMAN_CHANNEL_PSB_4947 = 48,
	CONNMAN_CHANNEL_PSB_4952 = 49,
	CONNMAN_CHANNEL_PSB_4957 = 50,
	CONNMAN_CHANNEL_PSB_4962 = 51,
	CONNMAN_CHANNEL_PSB_4967 = 52,
	CONNMAN_CHANNEL_PSB_4972 = 53,
	CONNMAN_CHANNEL_PSB_4977 = 54,
	CONNMAN_CHANNEL_PSB_4982 = 55,
	CONNMAN_CHANNEL_PSB_4985 = 56,
	CONNMAN_CHANNEL_PSB_4986 = 57,
	CONNMAN_CHANNEL_PSB_4987 = 58,
	CONNMAN_CHANNEL_PSB_4988 = 59,
	CONNMAN_CHANNEL_PSB_4989 = 60,
#endif
	CONNMAN_CHANNEL_MAX
};
const char *kMetricNetworkChannel = "Network.%c%s.Channel";
const int kMetricNetworkChannelMax = CONNMAN_CHANNEL_MAX;

const char *kMetricNetworkPhyMode = "Network.%c%s.PhyMode";
const int kMetricNetworkPhyModeMax = CONNMAN_NETWORK_PHYMODE_MAX;

static int is_suspended = FALSE;

/*
 * Set to the current time when resume event occurs.  Cleared when the ready
 * state is reached.
 */
static GTimeVal time_of_resume;

static void metrics_system_suspend(void)
{
	_DBG_METRICS("");
	is_suspended = TRUE;
}

static void metrics_system_resume(void)
{
	_DBG_METRICS("");
	is_suspended = FALSE;
	g_get_current_time(&time_of_resume);
}

static void clear_time_of_resume()
{
	memset(&time_of_resume, 0, sizeof(time_of_resume));
}

static connman_bool_t is_timeset(const GTimeVal *tv)
{
	return !(tv->tv_sec == 0 && tv->tv_usec == 0);
}

static void __network_metric_name(char *name, size_t name_len,
    const char *type, const char *key)
{
	/* NB: we append the network type but capitalized */
	/* TODO(sleffler) maybe map type entirely; e.g. "wifi" -> "WiFi" */
	g_snprintf(name, name_len, key, toupper(type[0]), type+1);
}

static void network_metric_name(char *name, size_t name_len,
    const struct connman_service *service, const char *key)
{
	const char *type = connman_service_get_type(service);
	CONNMAN_ASSERT(type != NULL);
	__network_metric_name(name, name_len, type, key);
}

static void send_to_uma(const char *name, int value, int min, int max,
    int nbuckets)
{
	if (!CMetricsLibrarySendToUMA(lib, name, value, min, max, nbuckets))
		connman_error("error sending metric %s", name);
}

static void send_enum_to_uma(const char *name, int value, int max)
{
	if (!CMetricsLibrarySendEnumToUMA(lib, name, value, max))
		connman_error("error sending metric %s", name);
}

static void metrics_default_changed(struct connman_service *service)
{
	static int was_online = FALSE;		/* NB: start offline */
	static time_t last_change = 0;
	static time_t last_default_change = 0;
	static const char *last_default_type = "";
	time_t now = time(NULL);
	const char *type;

	_DBG_METRICS("service %s was_online %d is_suspended %d delta %d secs",
	    service != NULL ? connman_service_get_identifier(service) : NULL,
	    was_online, is_suspended, (int)(now - last_change));

	/*
	 * NB: we cannot record the service ptr w/o holding a
	 * reference as the device may go away (e.g. a usb device).
	 * But we just need the type and connman_service_get_type
	 * is known to return ptr's to stable storage so just use
	 * that to detect technology switching.
	 */
	type = connman_service_get_type(service);
	if (g_strcmp0(type, last_default_type) != 0) {
		/*
		 * Type of default service changed; calculate the
		 * TimeOnline for the previous service type so we can track
		 * how much time is spent on each technology with:
		 *
		 *  PerCent(sum(TimeOnline.<tech>), sum(TimeOnline.*))
		 *
		 * Note we do not include time suspended so this time is
		 * real time on the network (unlike TimeToDrop).
		 */
		if (g_strcmp0(last_default_type, "") != 0) {
			char name[METRIC_NAME_LEN];
			__network_metric_name(name, sizeof(name),
			    last_default_type, kMetricNetworkTimeOnlineName);
			send_to_uma(name,  now - last_default_change,
			    kMetricNetworkTimeOnlineMin,
			    kMetricNetworkTimeOnlineMax,
			    kMetricNetworkTimeOnlineBuckets);

			_DBG_METRICS("send_to_uma %s %d",
			    name, (int)(now - last_default_change));
		}
		last_default_type = type;
		last_default_change = now;
	}

	/*
	 * Ignore changes when suspending.  This assumes the suspend
	 * notification arrives before the change to the default service
	 * state which looks to be true.
	 */
	if (is_suspended)
		return;
	/*
	 * Ignore changes that are not online/offline transitions; e.g.
	 * switching between wired and wireless.  TimeToDrop measures
	 * time online regardless of how we are connected.
	 */
	if ((service == NULL && !was_online) || (service != NULL && was_online))
		return;

	if (service == NULL) {
		/*
		 * Calculate overall TimeToDrop; this is the time spent
		 * online ignoring transitions between devices.
		 */
		send_to_uma(kMetricNetworkTimeToDropName, now - last_change,
		    kMetricNetworkTimeToDropMin,
		    kMetricNetworkTimeToDropMax,
		    kMetricNetworkTimeToDropBuckets);
	}
	was_online = (service != NULL);
	last_change = now;
}

static void send_msec_to_uma(const struct connman_service *service,
		const char *key, long secs, long usecs)
{
	long msecs;
	char name[METRIC_NAME_LEN];

	msecs = secs * 1000 + (usecs / 1000);
	network_metric_name(name, sizeof(name), service, key);
	send_to_uma(name, (int) msecs, 1, 45 * 1000, 50);
}
static void send_state_delta(const struct connman_service *service,
	const char *key,
	enum connman_service_state from, enum connman_service_state to)
{
	long secs, usecs;

	connman_service_get_time_delta(service, from, to, &secs, &usecs);
	send_msec_to_uma(service, key, secs, usecs);
}

static void send_service_error(const struct connman_service *service)
{
	const enum connman_service_error error =
	    connman_service_get_error(service);

	_DBG_METRICS("error %d", error);
	send_enum_to_uma(kMetricNetworkServiceErrors, error,
	    kMetricNetworkServiceErrorsMax);
}

static void maybe_send_resume_to_ready(const struct connman_service *service)
{
	long secs, usecs;

	if (!is_timeset(&time_of_resume))
		return;

	connman_service_get_time(service, CONNMAN_SERVICE_STATE_READY, &secs,
	    &usecs);
	secs -= time_of_resume.tv_sec;
	usecs -= time_of_resume.tv_usec;
	if (usecs < 0) {
		secs--;
		usecs += 1000 * 1000;
	}

	_DBG_METRICS("secs %ld usecs %ld", secs, usecs);
	send_msec_to_uma(service, kMetricNetworkTimeResumeToReady, secs, usecs);
}

static enum connman_authmode map_authmode(const char *mode)
{
	/* NB: order some more common ones first */
	if (g_strcmp0(mode, "EAP-TLS") == 0)
		return CONNMAN_AUTHMODE_EAP_TLS;
	if (g_strcmp0(mode, "EAP-TTLS") == 0)
		return CONNMAN_AUTHMODE_EAP_TTLS;
	if (g_strcmp0(mode, "EAP-MSCHAPV2") == 0)
		return CONNMAN_AUTHMODE_EAP_MSCHAPV2;
	if (g_strcmp0(mode, "EAP-MD5") == 0)
		return CONNMAN_AUTHMODE_EAP_MD5;

	if (g_strcmp0(mode, "EAP-AKA") == 0)
		return CONNMAN_AUTHMODE_EAP_AKA;
	if (g_strcmp0(mode, "EAP-FAST") == 0)
		return CONNMAN_AUTHMODE_EAP_FAST;
	if (g_strcmp0(mode, "EAP-GPSK") == 0)
		return CONNMAN_AUTHMODE_EAP_GPSK;
	if (g_strcmp0(mode, "EAP-GTC") == 0)
		return CONNMAN_AUTHMODE_EAP_GTC;
	if (g_strcmp0(mode, "EAP-IKEV2") == 0)
		return CONNMAN_AUTHMODE_EAP_IKEV2;
	if (g_strcmp0(mode, "EAP-LEAP") == 0)
		return CONNMAN_AUTHMODE_EAP_LEAP;
	if (g_strcmp0(mode, "EAP-OTP") == 0)
		return CONNMAN_AUTHMODE_EAP_OTP;
	if (g_strcmp0(mode, "EAP-PAX") == 0)
		return CONNMAN_AUTHMODE_EAP_PAX;
	if (g_strcmp0(mode, "EAP-PEAP") == 0)
		return CONNMAN_AUTHMODE_EAP_PEAP;
	if (g_strcmp0(mode, "EAP-PSK") == 0)
		return CONNMAN_AUTHMODE_EAP_PSK;
	if (g_strcmp0(mode, "EAP-SAKE") == 0)
		return CONNMAN_AUTHMODE_EAP_SAKE;
	if (g_strcmp0(mode, "EAP-SIM") == 0)
		return CONNMAN_AUTHMODE_EAP_SIM;
	if (g_strcmp0(mode, "EAP-TNC") == 0)
		return CONNMAN_AUTHMODE_EAP_TNC;

	if (mode != NULL)
		connman_warn("%s: unknown authmode %s", __func__, mode);
	return CONNMAN_AUTHMODE_UNKNOWN;
}

static void send_service_security(struct connman_service *service)
{
	const enum connman_service_security security =
	    connman_service_get_security(service);
	char name[METRIC_NAME_LEN];

	_DBG_METRICS("security %d", security);
	network_metric_name(name, sizeof(name), service,
	    kMetricNetworkSecurity);
	send_enum_to_uma(name, security, kMetricNetworkSecurityMax);

	/*
	 * For 802.1x security send the negotiated EAP method.
	 */
	if (security == CONNMAN_SERVICE_SECURITY_802_1X) {
		const enum connman_authmode authmode = map_authmode(
		    connman_service_get_authmode(service));

		_DBG_METRICS("authmode %d", authmode);
		network_metric_name(name, sizeof(name), service,
		    kMetricNetworkAuthMode);
		send_enum_to_uma(name, authmode, kMetricNetworkAuthModeMax);
	}
}

/*
 * Map WiFi frequency to UMA enum value.
 */
static enum connman_channel __map_frequency(int frequency)
{
	if (2412 <= frequency && frequency <= 2472) {
		if (((frequency - 2412) % 5) == 0)
			return CONNMAN_CHANNEL_2412 + (frequency - 2412) / 5;
	} else if (frequency == 2484) {
		return CONNMAN_CHANNEL_2484;
	} else if (5170 <= frequency && frequency <= 5230) {
		if ((frequency % 20) == 0)
			return CONNMAN_CHANNEL_5180 + (frequency - 5180) / 20;
		if ((frequency % 20) == 10)
			return CONNMAN_CHANNEL_5170 + (frequency - 5170) / 20;
		/* NB: fall through to return undefined */
	} else if (5240 <= frequency && frequency <= 5320) {
		if (((frequency - 5180) % 20) == 0)
			return CONNMAN_CHANNEL_5180 + (frequency - 5180) / 20;
	} else if (5500 <= frequency && frequency <= 5700) {
		if (((frequency - 5500) % 20) == 0)
			return CONNMAN_CHANNEL_5500 + (frequency - 5500) / 20;
	} else if (5745 <= frequency && frequency <= 5825) {
		if (((frequency - 5745) % 20) == 0)
			return CONNMAN_CHANNEL_5745 + (frequency - 5745) / 20;
#ifdef CONFIG_PSB_SUPPORT
	} else if (4940 <= frequency && frequency <= 4990) {
		/* Public Safety Band */
		return CONNMAN_CHANNEL_PSB_4940 + (frequency * 10) +
		    ((frequency % 5) == 2 ? 5 : 0) - 49400) / 5;
#endif
	}
	connman_info("%s: no mapping for WiFi frequency %d", __func__,
	    frequency);
	return CONNMAN_CHANNEL_UNDEF;
}

static void send_service_channel(struct connman_service *service)
{
	int frequency = connman_service_get_frequency(service);
	enum connman_channel channel;
	char name[METRIC_NAME_LEN];

	network_metric_name(name, sizeof(name), service, kMetricNetworkChannel);
	/*
	 * Map frequency to UMA enum value.
	 */
	channel = __map_frequency(frequency);
	_DBG_METRICS("map %d to %d", frequency, channel);
	send_enum_to_uma(name, channel, kMetricNetworkChannelMax);
}

static void send_service_phymode(struct connman_service *service)
{
	enum connman_network_phymode phymode =
	    connman_service_get_phymode(service);
	char name[80];

	network_metric_name(name, sizeof(name), service, kMetricNetworkPhyMode);
	send_enum_to_uma(name, phymode, kMetricNetworkPhyModeMax);
}

static void metrics_service_state_changed(struct connman_service *service)
{
	const char *state = connman_service_get_state(service);
	const char *type = connman_service_get_type(service);

	_DBG_METRICS("service %s state %s", service != NULL ?
	    connman_service_get_identifier(service) : NULL, state);

	if (strcmp(state, "failure") == 0)
		send_service_error(service);

	if (strcmp(state, "online") == 0) {
		/*
		 * Time to online is the time from when the network is
		 * marked "ready" until we can retrieve a webpage
		 * indicating connectivity.
		 */
		send_state_delta(service, kMetricNetworkTimeToOnline,
				 CONNMAN_SERVICE_STATE_READY,
				 CONNMAN_SERVICE_STATE_ONLINE);
		return;
	}

	if (strcmp(state, "portal") == 0) {
		/*
		 * Time to portal is usually the same as the timeout
		 * used for portal detection, but it will be less when
		 * the restricted network hijacks DNS and redirects
		 * HTTP requests to a captive portal webserver.
		 */
		send_state_delta(service, kMetricNetworkTimeToPortal,
				 CONNMAN_SERVICE_STATE_READY,
				 CONNMAN_SERVICE_STATE_PORTAL);
		return;
	}

	if (strcmp(state, "ready") != 0)
		return;

	if (strcmp(type, "wifi") == 0) {
		/*
		 * Time to join a network covers scan+auth+assoc.  This
		 * is presently provided only for wifi networks; might
		 * want to collect this for other networks.
		 */
		send_state_delta(service, kMetricNetworkTimeToJoinName,
		    CONNMAN_SERVICE_STATE_ASSOCIATION,
		    CONNMAN_SERVICE_STATE_CONFIGURATION);

		/*
		 * If this is the first time the WiFi network is ready after a
		 * resume, send the time from the resume event to the ready
		 * event.
		 */
		maybe_send_resume_to_ready(service);

		/*
		 * BSS channel (frequency); mapped to an enum.
		 */
		send_service_channel(service);
		/*
		 * Description of the channel capabilities.
		 */
		send_service_phymode(service);
		/*
		 * All services have a security type, but this is
		 * really only meaningful for WiFi.
		 */
		send_service_security(service);
	}

	/*
	 * Subsequent connections without a resume should not report a
	 * TimeResumeToReady.
	*/
	clear_time_of_resume();

	/*
	 * Time to config a network covers Layer 3 configuration
	 * work (typically acquiring a DHCP lease).
	 */
	send_state_delta(service, kMetricNetworkTimeToConfigName,
	    CONNMAN_SERVICE_STATE_CONFIGURATION,
	    CONNMAN_SERVICE_STATE_READY);
}

static struct connman_notifier metrics_notifier = {
	.name			= "metrics",
	.priority		= CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
	.default_changed	= metrics_default_changed,
	.service_state_changed	= metrics_service_state_changed,
	.system_suspend		= metrics_system_suspend,
	.system_resume		= metrics_system_resume,
};

static int metrics_init(void)
{
	if (connman_notifier_register(&metrics_notifier) < 0) {
		connman_error("Failed to register metrics notifier");
		return -1;
	}
	lib = CMetricsLibraryNew();	/* NB: does not return NULL */
	CMetricsLibraryInit(lib);
	clear_time_of_resume();
	return 0;
}

static void metrics_finis(void)
{
	CMetricsLibraryDelete(lib);
	connman_notifier_unregister(&metrics_notifier);
}

CONNMAN_PLUGIN_DEFINE(crosmetrics, "Chrome OS metrics plugin", VERSION,
		CONNMAN_PLUGIN_PRIORITY_DEFAULT, metrics_init, metrics_finis)
