/**
 * @file oprof_start.cpp
 * The GUI start main class
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author Philippe Elie
 * @author John Levon
 */

#include <sys/stat.h>
#include <unistd.h>

#include <ctime>
#include <cstdio>
#include <cmath>
#include <sstream>
#include <iostream>
#include <fstream>
#include <algorithm>

#if QT3_SUPPORT
#include <Qt/qlineedit.h>
#include <Qt/qcheckbox.h>
#include <Qt/qtabwidget.h>
#include <Qt/qmessagebox.h>
#include <Qt/qvalidator.h>
#include <Qt/qlabel.h>
#include <Qt/qpushbutton.h>
#include <Qt/q3listview.h>
#include <Qt/q3combobox.h>
#include <Qt/q3listbox.h>
#include <Qt/q3filedialog.h>
#include <Qt/q3buttongroup.h>
#include <Qt/q3header.h>
#else
#include <qlineedit.h>
#include <qcheckbox.h>
#include <qtabwidget.h>
#include <qmessagebox.h>
#include <qvalidator.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlistview.h>
#include <qcombobox.h>
#include <qlistbox.h>
#include <qfiledialog.h>
#include <qbuttongroup.h>
#include <qheader.h>
#define Q3ListView QListView
#endif

#include "oprof_start.h"
#include "op_config.h"
#include "string_manip.h"
#include "op_cpufreq.h"
#include "op_alloc_counter.h"
#include "oprof_start_util.h"
#include "file_manip.h"

#include "op_hw_config.h"

using namespace std;

static char const * green_xpm[] = {
"16 16 2 1",
" 	c None",
".	c #00FF00",
"    .......     ",
"  ...........   ",
" .............  ",
" .............  ",
"............... ",
"............... ",
"............... ",
"............... ",
"............... ",
"............... ",
"............... ",
" .............  ",
" .............  ",
"  ...........   ",
"    .......     ",
"                " };

static char const * red_xpm[] = {
"16 16 2 1",
" 	c None",
".	c #FF0000",
"    .......     ",
"  ...........   ",
" .............  ",
" .............  ",
"............... ",
"............... ",
"............... ",
"............... ",
"............... ",
"............... ",
"............... ",
" .............  ",
" .............  ",
"  ...........   ",
"    .......     ",
"                " };

static QPixmap * green_pixmap;
static QPixmap * red_pixmap;
static op_event_descr null_evt;



op_event_descr::op_event_descr()
	:
	counter_mask(0),
	val(0),
	unit(0),
	min_count(0)
{
}


oprof_start::oprof_start()
	:
	oprof_start_base(0, 0, false, 0),
	event_count_validator(new QIntValidator(event_count_edit)),
	current_event(0),
	cpu_speed(op_cpu_frequency()),
	total_nr_interrupts(0)
{
	green_pixmap = new QPixmap(green_xpm);
	red_pixmap = new QPixmap(red_xpm);
	vector<string> args;
	args.push_back("--init");

	if (do_exec_command(OP_BINDIR "/opcontrol", args))
		exit(EXIT_FAILURE);

	cpu_type = op_get_cpu_type();
	op_nr_counters = op_get_nr_counters(cpu_type);

	if (cpu_type == CPU_TIMER_INT) {
		setup_config_tab->removePage(counter_setup_page);
	} else {
		fill_events();
	}

	op_interface interface = op_get_interface();
	if (interface == OP_INTERFACE_NO_GOOD) {
		QMessageBox::warning(this, 0, "Couldn't determine kernel"
		                     " interface version");
		exit(EXIT_FAILURE);
	}
	bool is_26 = interface == OP_INTERFACE_26;

	if (is_26) {
		note_table_size_edit->hide();
		note_table_size_label->hide();
		if (!op_file_readable("/dev/oprofile/backtrace_depth")) {
			callgraph_depth_label->hide();
			callgraph_depth_edit->hide();
		}
	} else {
		callgraph_depth_label->hide();
		callgraph_depth_edit->hide();
		buffer_watershed_label->hide();
		buffer_watershed_edit->hide();
		cpu_buffer_size_label->hide();
		cpu_buffer_size_edit->hide();
	}

	// setup the configuration page.
	kernel_filename_edit->setText(config.kernel_filename.c_str());

	no_vmlinux->setChecked(config.no_kernel);

	buffer_size_edit->setText(QString().setNum(config.buffer_size));
	buffer_watershed_edit->setText(QString().setNum(config.buffer_watershed));
	cpu_buffer_size_edit->setText(QString().setNum(config.cpu_buffer_size));
	note_table_size_edit->setText(QString().setNum(config.note_table_size));
	callgraph_depth_edit->setText(QString().setNum(config.callgraph_depth));
	verbose->setChecked(config.verbose);
	separate_lib_cb->setChecked(config.separate_lib);
	separate_kernel_cb->setChecked(config.separate_kernel);
	separate_cpu_cb->setChecked(config.separate_cpu);
	separate_thread_cb->setChecked(config.separate_thread);

	// the unit mask check boxes
	hide_masks();

	event_count_edit->setValidator(event_count_validator);
	QIntValidator * iv;
	iv = new QIntValidator(OP_MIN_BUF_SIZE, OP_MAX_BUF_SIZE, buffer_size_edit);
	buffer_size_edit->setValidator(iv);
	note_table_size_edit->setValidator(iv);
	iv = new QIntValidator(0, INT_MAX, callgraph_depth_edit);
	callgraph_depth_edit->setValidator(iv);
	iv = new QIntValidator(0, INT_MAX, buffer_watershed_edit);
	buffer_watershed_edit->setValidator(iv);
	iv = new QIntValidator(0, OP_MAX_CPU_BUF_SIZE, cpu_buffer_size_edit);
	cpu_buffer_size_edit->setValidator(iv);

	// daemon status timer
	startTimer(5000);
	timerEvent(0);

	resize(minimumSizeHint());

	// force the pixmap re-draw
	event_selected();
}


void oprof_start::fill_events()
{
	// we need to build the event descr stuff before loading the
	// configuration because we use locate_event to get an event descr
	// from its name.
	struct list_head * pos;
	struct list_head * events = op_events(cpu_type);

	list_for_each(pos, events) {
		struct op_event * event = list_entry(pos, struct op_event, event_next);

		op_event_descr descr;

		descr.counter_mask = event->counter_mask;
		descr.val = event->val;
		if (event->unit->num) {
			descr.unit = event->unit;
		} else {
			descr.unit = 0;
		}

		descr.name = event->name;
		descr.help_str = event->desc;
		descr.min_count = event->min_count;

		for (uint ctr = 0; ctr < op_nr_counters; ++ctr) {
			uint count;

			if (!(descr.counter_mask & (1 << ctr)))
				continue;

			if (cpu_type == CPU_RTC) {
				count = 1024;
			} else {
				/* setting to cpu Hz / 2000 gives a safe value for
				 * all events, and a good one for most.
				 */
				if (cpu_speed)
					count = int(cpu_speed * 500);
				else
					count = descr.min_count * 100;
			}

			event_cfgs[descr.name].count = count;
			event_cfgs[descr.name].umask = 0;
			if (descr.unit)
				event_cfgs[descr.name].umask = descr.unit->default_mask;
			event_cfgs[descr.name].os_ring_count = 1;
			event_cfgs[descr.name].user_ring_count = 1;
		}

		v_events.push_back(descr);
	}

	events_list->header()->hide();
	events_list->setSorting(-1);

	fill_events_listbox();

	read_set_events();

	// FIXME: why this ?
	if (cpu_type == CPU_RTC)
		events_list->setCurrentItem(events_list->firstChild());

	load_config_file();
}


namespace {

/// find the first item with the given text in column 0 or return NULL
Q3ListViewItem * findItem(Q3ListView * view, char const * name)
{
	// Qt 2.3.1 does not have QListView::findItem()
	Q3ListViewItem * item = view->firstChild();

	while (item && strcmp(item->text(0).latin1(), name))
		item = item->nextSibling();

	return item;
}

};


void oprof_start::setup_default_event()
{
	struct op_default_event_descr descr;
	op_default_event(cpu_type, &descr);

	event_cfgs[descr.name].umask = descr.um;
	event_cfgs[descr.name].count = descr.count;
	event_cfgs[descr.name].user_ring_count = 1;
	event_cfgs[descr.name].os_ring_count = 1;

	Q3ListViewItem * item = findItem(events_list, descr.name);
	if (item)
		item->setSelected(true);
}


void oprof_start::read_set_events()
{
	string name = get_config_filename(".oprofile/daemonrc");

	ifstream in(name.c_str());

	if (!in) {
		setup_default_event();
		return;
	}

	string str;

	bool one_enabled = false;

	while (getline(in, str)) {
		string const val = split(str, '=');
		string const name = str;

		if (!is_prefix(name, "CHOSEN_EVENTS_"))
			continue;

		one_enabled = true;

		// CHOSEN_EVENTS_#nr=CPU_CLK_UNHALTED:10000:0:1:1
		vector<string> parts = separate_token(val, ':');

		if (parts.size() != 5 && parts.size() != 2) {
			cerr << "invalid configuration file\n";
			// FIXME
			exit(EXIT_FAILURE);
		}

		string ev_name = parts[0];
		event_cfgs[ev_name].count =
			op_lexical_cast<unsigned int>(parts[1]);

		// CPU_CLK_UNHALTED:10000 is also valid
		if (parts.size() == 5) {
			event_cfgs[ev_name].umask =
				op_lexical_cast<unsigned int>(parts[2]);
			event_cfgs[ev_name].user_ring_count =
				op_lexical_cast<unsigned int>(parts[3]);
			event_cfgs[ev_name].os_ring_count =
				op_lexical_cast<unsigned int>(parts[4]);
		} else {
			event_cfgs[ev_name].umask = 0;
			event_cfgs[ev_name].user_ring_count = 1;
			event_cfgs[ev_name].os_ring_count = 1;
		}

		Q3ListViewItem * item = findItem(events_list, ev_name.c_str());
		if (item)
			item->setSelected(true);
	}

	// use default event if none set
	if (!one_enabled)
		setup_default_event();
}


void oprof_start::load_config_file()
{
	string name = get_config_filename(".oprofile/daemonrc");

	ifstream in(name.c_str());
	if (!in) {
		if (!check_and_create_config_dir())
			return;

		ofstream out(name.c_str());
		if (!out) {
			QMessageBox::warning(this, 0, "Unable to open configuration "
				"file ~/.oprofile/daemonrc");
		}
		return;
	}

	in >> config;
}


// user request a "normal" exit so save the config file.
void oprof_start::accept()
{
	// record the previous settings
	record_selected_event_config();

	save_config();

	QDialog::accept();
}


void oprof_start::closeEvent(QCloseEvent *)
{
	accept();
}


void oprof_start::timerEvent(QTimerEvent *)
{
	static time_t last = time(0);

	daemon_status dstat;

	flush_profiler_data_btn->setEnabled(dstat.running);
	stop_profiler_btn->setEnabled(dstat.running);
	start_profiler_btn->setEnabled(!dstat.running);
	reset_sample_files_btn->setEnabled(!dstat.running);

	if (!dstat.running) {
		daemon_label->setText("Profiler is not running.");
		return;
	}

	ostringstream ss;
	ss << "Profiler running:";

	time_t curr = time(0);
	total_nr_interrupts += dstat.nr_interrupts;

	if (curr - last)
		ss << " (" << dstat.nr_interrupts / (curr - last) << " interrupts / second, total " << total_nr_interrupts << ")";

	daemon_label->setText(ss.str().c_str());

	last = curr;
}


void oprof_start::fill_events_listbox()
{
	setUpdatesEnabled(false);

	for (vector<op_event_descr>::reverse_iterator cit = v_events.rbegin();
	     cit != v_events.rend(); ++cit) {
		new Q3ListViewItem(events_list, cit->name.c_str());
	}

	setUpdatesEnabled(true);
	update();
}


void oprof_start::display_event(op_event_descr const & descr)
{
	setUpdatesEnabled(false);

	setup_unit_masks(descr);
	os_ring_count_cb->setEnabled(true);
	user_ring_count_cb->setEnabled(true);
	event_count_edit->setEnabled(true);

	event_setting & cfg = event_cfgs[descr.name];

	os_ring_count_cb->setChecked(cfg.os_ring_count);
	user_ring_count_cb->setChecked(cfg.user_ring_count);
	QString count_text;
	count_text.setNum(cfg.count);
	event_count_edit->setText(count_text);
	event_count_validator->setRange(descr.min_count, max_perf_count());

	setUpdatesEnabled(true);
	update();
}


bool oprof_start::is_selectable_event(Q3ListViewItem * item)
{
	if (item->isSelected())
		return true;

	selected_events.insert(item);

	bool ret = false;
	if (alloc_selected_events())
		ret = true;

	selected_events.erase(item);

	return ret;
}


void oprof_start::draw_event_list()
{
	Q3ListViewItem * cur;
	for (cur = events_list->firstChild(); cur; cur = cur->nextSibling()) {
		if (is_selectable_event(cur))
			cur->setPixmap(0, *green_pixmap);
		else
			cur->setPixmap(0, *red_pixmap);
	}
}


bool oprof_start::alloc_selected_events() const
{
	vector<op_event const *> events;

	set<Q3ListViewItem *>::const_iterator it;
	for (it = selected_events.begin(); it != selected_events.end(); ++it)
		events.push_back(find_event_by_name((*it)->text(0).latin1(),0,0));

	size_t * map =
		map_event_to_counter(&events[0], events.size(), cpu_type);

	if (!map)
		return false;

	free(map);
	return true;
}

void oprof_start::event_selected()
{
	// The deal is simple: QT lack of a way to know what item was the last
	// (de)selected item so we record a set of selected items and diff
	// it in the appropriate way with the previous list of selected items.

	set<Q3ListViewItem *> current_selection;
	Q3ListViewItem * cur;
	for (cur = events_list->firstChild(); cur; cur = cur->nextSibling()) {
		if (cur->isSelected())
			current_selection.insert(cur);
	}

	// First remove the deselected item.
	vector<Q3ListViewItem *> new_deselected;
	set_difference(selected_events.begin(), selected_events.end(),
		       current_selection.begin(), current_selection.end(),
		       back_inserter(new_deselected));
	vector<Q3ListViewItem *>::const_iterator it;
	for (it = new_deselected.begin(); it != new_deselected.end(); ++it)
		selected_events.erase(*it);

	// Now try to add the newly selected item if enough HW resource exists
	vector<Q3ListViewItem *> new_selected;
	set_difference(current_selection.begin(), current_selection.end(),
		       selected_events.begin(), selected_events.end(),
		       back_inserter(new_selected));
	for (it = new_selected.begin(); it != new_selected.end(); ++it) {
		selected_events.insert(*it);
		if (!alloc_selected_events()) {
			(*it)->setSelected(false);
			selected_events.erase(*it);
		} else {
			current_event = *it;
		}
	}

	draw_event_list();

	if (current_event)
		display_event(locate_event(current_event->text(0).latin1()));
}


void oprof_start::event_over(Q3ListViewItem * item)
{
	op_event_descr const & descr = locate_event(item->text(0).latin1());

	string help_str = descr.help_str.c_str();
	if (!is_selectable_event(item)) {
		help_str += " conflicts with:";

		set<Q3ListViewItem *>::const_iterator it;
		for (it = selected_events.begin(); 
		     it != selected_events.end(); ) {
			Q3ListViewItem * temp = *it;
			selected_events.erase(it++);
			if (is_selectable_event(item)) {
				help_str += " ";
				help_str += temp->text(0).latin1();
			}
			selected_events.insert(temp);
		}
	}

	event_help_label->setText(help_str.c_str());
}


/// select the kernel image filename
void oprof_start::choose_kernel_filename()
{
	string name = kernel_filename_edit->text().latin1();
	string result = do_open_file_or_dir(name, false);

	if (!result.empty())
		kernel_filename_edit->setText(result.c_str());
}


// this record the current selected event setting in the event_cfg[] stuff.
// FIXME: need validation?
void oprof_start::record_selected_event_config()
{
	if (!current_event)
		return;

	string name(current_event->text(0).latin1());

	event_setting & cfg = event_cfgs[name];
	op_event_descr const & curr = locate_event(name);

	cfg.count = event_count_edit->text().toUInt();
	cfg.os_ring_count = os_ring_count_cb->isChecked();
	cfg.user_ring_count = user_ring_count_cb->isChecked();
	cfg.umask = get_unit_mask(curr);
}


// validate and save the configuration (The qt validator installed
// are not sufficient to do the validation)
bool oprof_start::record_config()
{
	config.kernel_filename = kernel_filename_edit->text().latin1();
	config.no_kernel = no_vmlinux->isChecked();

	uint temp = buffer_size_edit->text().toUInt();
	if (temp < OP_MIN_BUF_SIZE || temp > OP_MAX_BUF_SIZE) {
		ostringstream error;

		error << "buffer size out of range: " << temp
		      << " valid range is [" << OP_MIN_BUF_SIZE << ", "
		      << OP_MAX_BUF_SIZE << "]";

		QMessageBox::warning(this, 0, error.str().c_str());

		return false;
	}
	config.buffer_size = temp;

	temp = buffer_watershed_edit->text().toUInt();
	// watershed above half of buffer size make little sense.
	if (temp > config.buffer_size / 2) {
		ostringstream error;

		error << "buffer watershed out of range: " << temp
		      << " valid range is [0 (use default), buffer size/2] "
		      << "generally 0.25 * buffer size is fine";

		QMessageBox::warning(this, 0, error.str().c_str());

		return false;
	}
	config.buffer_watershed = temp;

	temp = cpu_buffer_size_edit->text().toUInt();
	if ((temp != 0 && temp < OP_MIN_CPU_BUF_SIZE) ||
	    temp > OP_MAX_CPU_BUF_SIZE) {
		ostringstream error;

		error << "cpu buffer size out of range: " << temp
		      << " valid range is [" << OP_MIN_CPU_BUF_SIZE << ", "
		      << OP_MAX_CPU_BUF_SIZE << "] (size = 0: use default)";

		QMessageBox::warning(this, 0, error.str().c_str());

		return false;
	}
	config.cpu_buffer_size = temp;

	// Note table size is a 2.4 kernel thingy.  We'll just set it to
	// zero here since it's not used.
	// FIXME: Some day we should do a proper cleanup of the GUI to remove
	//        all leftover junk having anything to do with 2.4 kernels.
	config.note_table_size = 0;

	temp = callgraph_depth_edit->text().toUInt();
	if (temp > INT_MAX) {
		ostringstream error;

		error << "callgraph depth  out of range: " << temp
		      << " valid range is [" << 0 << ", "
		      << INT_MAX << "]";

		QMessageBox::warning(this, 0, error.str().c_str());

		return false;
	}
	config.callgraph_depth = temp;

	config.verbose = verbose->isChecked();
	config.separate_lib = separate_lib_cb->isChecked();
	config.separate_kernel = separate_kernel_cb->isChecked();
	config.separate_cpu = separate_cpu_cb->isChecked();
	config.separate_thread = separate_thread_cb->isChecked();

	return true;
}


void oprof_start::get_unit_mask_part(op_event_descr const & descr, uint num,
                                     bool selected, uint & mask)
{
	if (!selected)
		return;
	if  (num >= descr.unit->num)
		return;

	if (descr.unit->unit_type_mask == utm_bitmask)
		mask |= descr.unit->um[num].value;
	else
		mask = descr.unit->um[num].value;
}


// return the unit mask selected through the unit mask check box
uint oprof_start::get_unit_mask(op_event_descr const & descr)
{
	uint mask = 0;

	if (!descr.unit)
		return 0;

	// mandatory mask is transparent for user.
	if (descr.unit->unit_type_mask == utm_mandatory) {
		mask = descr.unit->default_mask;
		return mask;
	}

	get_unit_mask_part(descr, 0, check0->isChecked(), mask);
	get_unit_mask_part(descr, 1, check1->isChecked(), mask);
	get_unit_mask_part(descr, 2, check2->isChecked(), mask);
	get_unit_mask_part(descr, 3, check3->isChecked(), mask);
	get_unit_mask_part(descr, 4, check4->isChecked(), mask);
	get_unit_mask_part(descr, 5, check5->isChecked(), mask);
	get_unit_mask_part(descr, 6, check6->isChecked(), mask);
	get_unit_mask_part(descr, 7, check7->isChecked(), mask);
	get_unit_mask_part(descr, 8, check8->isChecked(), mask);
	get_unit_mask_part(descr, 9, check9->isChecked(), mask);
	get_unit_mask_part(descr, 10, check10->isChecked(), mask);
	get_unit_mask_part(descr, 11, check11->isChecked(), mask);
	get_unit_mask_part(descr, 12, check12->isChecked(), mask);
	get_unit_mask_part(descr, 13, check13->isChecked(), mask);
	get_unit_mask_part(descr, 14, check14->isChecked(), mask);
	get_unit_mask_part(descr, 15, check15->isChecked(), mask);
	return mask;
}


void oprof_start::hide_masks()
{
	check0->hide();
	check1->hide();
	check2->hide();
	check3->hide();
	check4->hide();
	check5->hide();
	check6->hide();
	check7->hide();
	check8->hide();
	check9->hide();
	check10->hide();
	check11->hide();
	check12->hide();
	check13->hide();
	check14->hide();
	check15->hide();
}


void oprof_start::setup_unit_masks(op_event_descr const & descr)
{
#define OP_MAX_HANDLED_UMS 16
	op_unit_mask const * um = descr.unit;

	hide_masks();

	if (!um || um->unit_type_mask == utm_mandatory)
		return;

	if (um->num > OP_MAX_HANDLED_UMS) {
		ostringstream error;

		error << "Number of unit masks (" << um->num << ") is greater than max allowed ("
		      << OP_MAX_HANDLED_UMS << ").";
		QMessageBox::warning(this, 0, error.str().c_str());
		return;
	}


	event_setting & cfg = event_cfgs[descr.name];

	unit_mask_group->setExclusive(um->unit_type_mask == utm_exclusive);

	QCheckBox * check = NULL;

	for (size_t i = 0; i < um->num; ++i) {
		switch (i) {
			case 0: check = check0; break;
			case 1: check = check1; break;
			case 2: check = check2; break;
			case 3: check = check3; break;
			case 4: check = check4; break;
			case 5: check = check5; break;
			case 6: check = check6; break;
			case 7: check = check7; break;
			case 8: check = check8; break;
			case 9: check = check9; break;
			case 10: check = check10; break;
			case 11: check = check11; break;
			case 12: check = check12; break;
			case 13: check = check13; break;
			case 14: check = check14; break;
			case 15: check = check15; break;
		}
		check->setText(um->um[i].desc);
		if (um->unit_type_mask == utm_exclusive)
			check->setChecked(cfg.umask == um->um[i].value);
		else
			check->setChecked(cfg.umask & um->um[i].value);

		check->show();
	}
}


uint oprof_start::max_perf_count() const
{
	return cpu_type == CPU_RTC ? OP_MAX_RTC_COUNT : OP_MAX_PERF_COUNT;
}


void oprof_start::on_flush_profiler_data()
{
	vector<string> args;
	args.push_back("--dump");

	if (daemon_status().running)
		do_exec_command(OP_BINDIR "/opcontrol", args);
	else
		QMessageBox::warning(this, 0, "The profiler is not started.");
}


// user is happy of its setting.
void oprof_start::on_start_profiler()
{
	// save the current settings
	record_selected_event_config();

	bool one_enable = false;

	Q3ListViewItem * cur;
	for (cur = events_list->firstChild(); cur; cur = cur->nextSibling()) {
		if (!cur->isSelected())
			continue;

		// the missing reference is intended: gcc 2.91.66 can compile
		// "op_event_descr const & descr = ..." w/o a warning
		op_event_descr const descr =
			locate_event(cur->text(0).latin1());

		event_setting & cfg = event_cfgs[cur->text(0).latin1()];

		one_enable = true;

		if (!cfg.os_ring_count && !cfg.user_ring_count) {
			QMessageBox::warning(this, 0, "You must select to "
					 "profile at least one of user binaries/kernel");
			return;
		}

		if (cfg.count < descr.min_count || 
		    cfg.count > max_perf_count()) {
			ostringstream out;

			out << "event " << descr.name << " count of range: "
			    << cfg.count << " must be in [ "
			    << descr.min_count << ", "
			    << max_perf_count()
			    << "]";

			QMessageBox::warning(this, 0, out.str().c_str());
			return;
		}

		if (descr.unit &&
		    descr.unit->unit_type_mask == utm_bitmask &&
		    cfg.umask == 0) {
			ostringstream out;

			out << "event " << descr.name << " invalid unit mask: "
			    << cfg.umask << endl;

			QMessageBox::warning(this, 0, out.str().c_str());
			return;
		}
	}

	if (one_enable == false && cpu_type != CPU_TIMER_INT) {
		QMessageBox::warning(this, 0, "No counters enabled.\n");
		return;
	}

	if (daemon_status().running) {
		// gcc 2.91 work around
		int user_choice = 0;
		user_choice =
			QMessageBox::warning(this, 0,
					     "Profiler already started:\n\n"
					     "stop and restart it?",
					     "&Restart", "&Cancel", 0, 0, 1);

		if (user_choice == 1)
			return;

		// this flush profiler data also.
		on_stop_profiler();
	}

	vector<string> args;

	// save_config validate and setup the config
	if (save_config()) {
		// now actually start
		args.push_back("--start");
		if (config.verbose)
			args.push_back("--verbose");
		do_exec_command(OP_BINDIR "/opcontrol", args);
	}

	total_nr_interrupts = 0;
	timerEvent(0);
}


bool oprof_start::save_config()
{
	if (!record_config())
		return false;

	vector<string> args;

	// saving config is done by running opcontrol --setup with appropriate
	// setted parameters so we use the same config file as command line
	// tools

	args.push_back("--setup");

	bool one_enabled = false;

	vector<string> tmpargs;
	tmpargs.push_back("--setup");

	Q3ListViewItem * cur;
	for (cur = events_list->firstChild(); cur; cur = cur->nextSibling()) {
		if (!cur->isSelected())
			continue;

		event_setting & cfg = event_cfgs[cur->text(0).latin1()];

		op_event_descr const & descr =
			locate_event(cur->text(0).latin1());

		one_enabled = true;

		string arg = "--event=" + descr.name;
		arg += ":" + op_lexical_cast<string>(cfg.count);
		arg += ":" + op_lexical_cast<string>(cfg.umask);
		arg += ":" + op_lexical_cast<string>(cfg.os_ring_count);
		arg += ":" + op_lexical_cast<string>(cfg.user_ring_count);

		tmpargs.push_back(arg);
	}

	// only set counters if at least one is enabled
	if (one_enabled)
		args = tmpargs;

	if (config.no_kernel) {
		args.push_back("--no-vmlinux");
	} else {
		args.push_back("--vmlinux=" + config.kernel_filename);
	}

	args.push_back("--buffer-size=" +
	               op_lexical_cast<string>(config.buffer_size));

	args.push_back("--buffer-watershed=" +
	               op_lexical_cast<string>(config.buffer_watershed));
	args.push_back("--cpu-buffer-size=" +
	               op_lexical_cast<string>(config.cpu_buffer_size));
	if (op_file_readable("/dev/oprofile/backtrace_depth")) {
		args.push_back("--callgraph=" +
		               op_lexical_cast<string>(config.callgraph_depth));
	}

	string sep = "--separate=";

	if (config.separate_lib)
		sep += "library,";
	if (config.separate_kernel)
		sep += "kernel,";
	if (config.separate_cpu)
		sep += "cpu,";
	if (config.separate_thread)
		sep += "thread,";

	if (sep == "--separate=")
		sep += "none";
	args.push_back(sep);

	// 2.95 work-around, it didn't like return !do_exec_command() 
	bool ret = !do_exec_command(OP_BINDIR "/opcontrol", args);
	return ret;
}


// flush and stop the profiler if it was started.
void oprof_start::on_stop_profiler()
{
	vector<string> args;
	args.push_back("--shutdown");

	if (daemon_status().running)
		do_exec_command(OP_BINDIR "/opcontrol", args);
	else
		QMessageBox::warning(this, 0, "The profiler is already stopped.");

	timerEvent(0);
}


void oprof_start::on_separate_kernel_cb_changed(int state)
{
	if (state == 2)
		separate_lib_cb->setChecked(true);
}

void oprof_start::on_reset_sample_files()
{
	int ret = QMessageBox::warning(this, 0, "Are you sure you want to "
	       "reset your last profile session ?", "Yes", "No", 0, 0, 1);
	if (!ret) {
		vector<string> args;
		args.push_back("--reset");
		if (!do_exec_command(OP_BINDIR "/opcontrol", args))
			// the next timer event will overwrite the message
			daemon_label->setText("Last profile session reseted.");
		else
			QMessageBox::warning(this, 0,
			     "Can't reset profiling session.");
	}
}


/// function object for matching against name
class event_name_eq {
	string name_;
public:
	explicit event_name_eq(string const & s) : name_(s) {}
	bool operator()(op_event_descr const & d) const {
		return d.name == name_;
	}
};


// helper to retrieve an event descr through its name.
op_event_descr const & oprof_start::locate_event(string const & name) const
{
	vector<op_event_descr>::const_iterator it = find_if(v_events.begin(), v_events.end(),
	                                                    event_name_eq(name));

	// Failure to find the event should NEVER happen; I had to put this here to silence Coverity.
	if (it != v_events.end())
		return *it;

	QMessageBox::warning((oprof_start *)this, 0, "Could not locate event. Returning null event.");
	null_evt.help_str = "";
	null_evt.name = "";
	return null_evt;
}
