/**
 * @file opd_extended.c
 * OProfile Extended Feature
 *
 * @remark Copyright 2007-2009 OProfile authors
 * @remark Read the file COPYING
 *
 * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
 * Copyright (c) 2009 Advanced Micro Devices, Inc.
 */

#include "opd_extended.h"
#include "op_string.h"

#include <string.h>
#include <stdio.h>

/* This global variable is >= 0
 * if extended feature is enabled */
static int opd_ext_feat_index;

extern struct opd_ext_handlers ibs_handlers;

/**
 * OProfile Extended Feature Table
 *
 * This table contains a list of extended features.
 */
static struct opd_ext_feature ext_feature_table[] = {
	{"ibs", &ibs_handlers },
	{ NULL, NULL }
};


static int get_index_for_feature(char const * name)
{
	int ret = -1;
	unsigned int i;

	if(!name)
		return ret;

	for (i = 0 ; ext_feature_table[i].feature != NULL ; i++ ) {
		if(!strncmp(name, ext_feature_table[i].feature,
			strlen(ext_feature_table[i].feature))) {
			ret = i;
			break;
		}
	}

	return ret;
}


static inline int is_ext_enabled()
{
	if (opd_ext_feat_index >= 0
	&& ext_feature_table[opd_ext_feat_index].handlers != NULL)
		return 1;
	else
		return 0;
}


static inline int is_ext_sfile_enabled()
{
	if (opd_ext_feat_index >= 0
	&& ext_feature_table[opd_ext_feat_index].handlers != NULL
	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile != NULL)
		return 1;
	else
		return 0;
}


/**
 * Param "value" is the input from CML option with the format:
 *
 * <feature name>:<param1>:<param2>:<param3>:.....
 *
 * where param1,2.3,..n are optional.
 */
int opd_ext_initialize(char const * value)
{
	int ret = EXIT_FAILURE;
	char * tmp = NULL, * name = NULL, * args = NULL;

	if(!value) {
		opd_ext_feat_index = -1;
		return 0;
	}

	tmp = op_xstrndup(value, strlen(value));

	/* Parse feature name*/
	if((name = strtok_r(tmp, ":", &args)) == NULL)
		goto err_out;

	if((opd_ext_feat_index = get_index_for_feature(name)) < 0)
		goto err_out;

	ret = ext_feature_table[opd_ext_feat_index].handlers->ext_init(args);

	return ret;

err_out:
	fprintf(stderr,"opd_ext_initialize: Invalid extended feature option: %s\n", value);
	return ret;
}


void opd_ext_print_stats()
{
	if (is_ext_enabled()
	&& ext_feature_table[opd_ext_feat_index].handlers->ext_print_stats != NULL) {
		printf("\n-- OProfile Extended-Feature Statistics --\n");
		ext_feature_table[opd_ext_feat_index].handlers->ext_print_stats();
	}
}


/**
 * opd_sfile extended APIs
 */
void opd_ext_sfile_create(struct sfile * sf)
{
	/* Creating ext sfile only if extended feature is enable*/
	if (is_ext_sfile_enabled()
	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->create != NULL)
		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->create(sf);
}


void opd_ext_sfile_dup (struct sfile * to, struct sfile * from)
{
	/* Duplicate ext sfile only if extended feature is enable*/
	if (is_ext_sfile_enabled()
	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->dup != NULL)
		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->dup(to, from);
}


void opd_ext_sfile_close (struct sfile * sf)
{
	/* Close ext sfile only if extended feature is enable*/
	if (is_ext_sfile_enabled()
	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->close != NULL)
		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->close(sf);
}


void opd_ext_sfile_sync(struct sfile * sf)
{
	/* Sync ext sfile only if extended feature is enable*/
	if (is_ext_sfile_enabled()
	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->sync != NULL)
		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->sync(sf);
}


odb_t * opd_ext_sfile_get(struct transient const * trans, int is_cg)
{
	/* Get ext sfile only if extended feature is enable*/
	if (is_ext_sfile_enabled()
	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->get != NULL)
		return	ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->get(trans, is_cg);

	return NULL;
}


struct opd_event * opd_ext_find_counter_event(unsigned long counter)
{
	/* Only if extended feature is enable*/
	if (is_ext_sfile_enabled()
	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->find_counter_event != NULL)
		return	ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->find_counter_event(counter);

	return NULL;
}

