// SPDX-License-Identifier: LGPL-2.1

/*
 * Copyright (C) 2017 VMware Inc, Yordan Karadzhov <ykaradzhov@vmware.com>
 */

/**
 *  @file    KsModels.cpp
 *  @brief   Models for data representation.
 */

// KernelShark
#include "KsModels.hpp"
#include "KsWidgetsLib.hpp"
#include "KsUtils.hpp"

/** Create a default (empty) KsFilterProxyModel object. */
KsFilterProxyModel::KsFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent),
  _searchStop(false),
  _source(nullptr)
{}

/**
 * Returns False if the item in the row indicated by the sourceRow and
 * sourceParent should be filtered out. Otherwise returns True.
 */
bool
KsFilterProxyModel::filterAcceptsRow(int sourceRow,
				     [[maybe_unused]] const QModelIndex &sourceParent) const
{
	if (_data[sourceRow]->visible & KS_TEXT_VIEW_FILTER_MASK)
		return true;

	return false;
}

/** Provide the Proxy model with data. */
void KsFilterProxyModel::fill(KsDataStore *data)
{
	_data = data->rows();
}

/** Set the source model for this Proxy model. */
void KsFilterProxyModel::setSource(KsViewModel *s)
{
	QSortFilterProxyModel::setSourceModel(s);
	_source = s;
}

size_t KsFilterProxyModel::_search(int column,
				   const QString &searchText,
				   search_condition_func cond,
				   QList<int> *matchList,
				   int step,
				   int first, int last,
				   QProgressBar *pb,
				   QLabel *l,
				   int *lastRowSearched,
				   bool notify)
{
	int index, row, nRows(last - first + 1);
	int milestone(1), pbCount(1);
	QString item;

	if (nRows > KS_PROGRESS_BAR_MAX)
		milestone = pbCount = nRows / (KS_PROGRESS_BAR_MAX - step -
					       _searchProgress);
	else
		_searchProgress = KS_PROGRESS_BAR_MAX - nRows;

	/* Loop over the items of the proxy model. */
	for (index = first; index <= last; index += step) {
		/*
		 * Use the index of the proxy model to retrieve the value
		 * of the row number in the base model.
		 */
		row = mapRowFromSource(index);
		item = _source->getValueStr(column, row);
		if (cond(searchText, item))
			matchList->append(row);

		if (_searchStop) {
			if (lastRowSearched)
				*lastRowSearched = index;

			if (notify)
				_pbCond.notify_one();

			break;
		}

		/* Deal with the Progress bar of the seatch. */
		if ((index - first) >= milestone) {
			milestone += pbCount;
			if (notify) {
				/*
				 * This is a multi-threaded search. Notify
				 * the main thread to update the progress bar.
				 */
				std::lock_guard<std::mutex> lk(_mutex);
				++_searchProgress;
				_pbCond.notify_one();
			} else {
				if (pb) {
					pb->setValue(pb->value() + 1);
					++_searchProgress;
				}

				if (l)
					l->setText(QString(" %1").arg(matchList->count()));

				QApplication::processEvents();
			}
		}
	}

	return index;
}

/** @brief Search the content of the table for a data satisfying an abstract
 *	   condition.
 *
 * @param column: The number of the column to search in.
 * @param searchText: The text to search for.
 * @param cond: Matching condition function.
 * @param matchList: Output location for a list containing the row indexes of
 *		     the cells satisfying matching condition.
 * @param pb: Input location for a Progressbar used to visualize the progress
 *	      of the search.
 * @param l: Input location for a label used to show the number of cells found.
 *
 * @returns The number of cells satisfying the matching condition.
 */
size_t KsFilterProxyModel::search(int column,
				  const QString &searchText,
				  search_condition_func cond,
				  QList<int> *matchList,
				  QProgressBar *pb,
				  QLabel *l)
{
	int nRows = rowCount({});
	_search(column,
		searchText,
		cond,
		matchList,
		1,		// step
		0,		// first
		nRows - 1,	// last
		pb,
		l,
		nullptr,
		false);

	return matchList->count();
}

/** @brief Search the content of the table for a data satisfying an abstract
 *	   condition.
 *
 * @param sm: Input location for the Search State machine object.
 * @param matchList: Output location for a list containing the row indexes of
 *
 * @returns The number of cells satisfying the matching condition.
 */
size_t KsFilterProxyModel::search(KsSearchFSM *sm, QList<int> *matchList)
{
	int nRows = rowCount({});

	_search(sm->column(),
		sm->searchText(),
		sm->condition(),
		matchList,
		1,				// step
		sm->_lastRowSearched + 1,	// first
		nRows - 1,			// last
		&sm->_searchProgBar,
		&sm->_searchCountLabel,
		&sm->_lastRowSearched,
		false);

	return matchList->count();
}

/** @brief Search the content of the table for a data satisfying an abstract
 *	   condition.
 *
 * @param column: The number of the column to search in.
 * @param searchText: The text to search for.
 * @param cond: Matching condition function.
 * @param step: The step used by the thread of the search when looping over
 *		the data.
 * @param first: Row index specifying the position inside the table from
 *		 where the search starts.
 * @param last:  Row index specifying the position inside the table from
 *		 where the search ends.
 * @param lastRowSearched: Output location for parameter showing the index of
 *			   the last searched item (data row).
 * @param notify: Input location for flag specifying if the search has to
 *		  notify the main thread when to update the progress bar.
 *
 * @returns A list containing the row indexes of the cells satisfying matching
 *	    condition.
 */
QList<int> KsFilterProxyModel::searchThread(int column,
					    const QString &searchText,
					    search_condition_func cond,
					    int step,
					    int first,
					    int last,
					    int *lastRowSearched,
					    bool notify)
{
	QList<int> matchList;
	_search(column,
		searchText,
		cond,
		&matchList,
		step,
		first,
		last,
		nullptr,
		nullptr,
		lastRowSearched,
		notify);

	return matchList;
}

int KsFilterProxyModel::mapRowFromSource(int r) const
{
	/*
	 * This works because the row number is shown in column
	 * TRACE_VIEW_COL_INDEX (or TRACE_VIEW_COL_INDEX - 1 in the case when
	 * the Stream Id column is hidden).
	 */
	int column = KsViewModel::TRACE_VIEW_COL_INDEX;

	if(_source->singleStream())
		column--;

	return this->data(this->index(r, column)).toInt();
}

/** Create default (empty) KsViewModel object. */
KsViewModel::KsViewModel(QObject *parent)
: QAbstractTableModel(parent),
  _data(nullptr),
  _nRows(0),
  _markA(KS_NO_ROW_SELECTED),
  _markB(KS_NO_ROW_SELECTED),
  _singleStream(true)
{
	_updateHeader();
}

/** Update the list of table headers. */
void KsViewModel::_updateHeader()
{
	beginRemoveColumns(QModelIndex(), 0, _header.count());
	endRemoveColumns();

	_header.clear();

	if (KsUtils::getNStreams() > 1) {
		_header << " >> ";
		_singleStream = false;
	} else {
		_singleStream = true;
	}

	_header << "#" << "CPU" << "Time Stamp" << "Task" << "PID"
		<< "Latency" << "Event" << "Info";

	beginInsertColumns(QModelIndex(), 0, _header.count() - 1);
	endInsertColumns();
}

/**
 * Get the data stored under the given role for the item referred to by
 * the index. This is an implementation of the pure virtual method of the
 * abstract model class.
 */
QVariant KsViewModel::data(const QModelIndex &index, int role) const
{
	if (role == Qt::ForegroundRole) {
		if (index.row() == _markA && index.column() != 0)
			return QVariant::fromValue(QColor(Qt::white));

		if (index.row() == _markB && index.column() != 0)
			return QVariant::fromValue(QColor(Qt::white));
	}

	if (role == Qt::BackgroundRole) {
		if (index.row() == _markA)
			return QVariant::fromValue(QColor(_colorMarkA));

		if (index.row() == _markB)
			return QVariant::fromValue(QColor(_colorMarkB));

		if (index.column() == TRACE_VIEW_COL_STREAM &&
		    !_singleStream) {
			int sd = _data[index.row()]->stream_id;
			QColor col;
			col << KsPlot::getColor(&_streamColors, sd);

			return QVariant::fromValue(col);
		}
	}

	if (role == Qt::DisplayRole)
		if (index.isValid())
			return this->getValue(index.column(), index.row());

	return {};
}

/** Get the string data stored in a given cell of the table. */
QString KsViewModel::getValueStr(int column, int row) const
{
	char *buffer;
	int pid;

	/*
	 * If only one Data stream (file) is loaded, the first column
	 * (TRACE_VIEW_COL_STREAM) is not shown.
	 */
	if(_singleStream)
		column++;

	auto lanMakeString = [&buffer] () {
		QString str(buffer);
		free(buffer);
		return str;
	};

	switch (column) {
		case TRACE_VIEW_COL_STREAM :
			return QString("%1").arg(_data[row]->stream_id);

		case TRACE_VIEW_COL_INDEX :
			return QString("%1").arg(row);

		case TRACE_VIEW_COL_CPU:
			return QString("%1").arg(_data[row]->cpu);

		case TRACE_VIEW_COL_TS:
			return KsUtils::Ts2String(_data[row]->ts, 6);

		case TRACE_VIEW_COL_COMM:
			buffer = kshark_get_task(_data[row]);
			return lanMakeString();

		case TRACE_VIEW_COL_PID:
			pid = kshark_get_pid(_data[row]);
			return QString("%1").arg(pid);

		case TRACE_VIEW_COL_AUX:
			buffer = kshark_get_aux_info(_data[row]);
			return lanMakeString();

		case TRACE_VIEW_COL_EVENT:
			buffer = kshark_get_event_name(_data[row]);
			return lanMakeString();

		case TRACE_VIEW_COL_INFO :
			buffer = kshark_get_info(_data[row]);
			return lanMakeString();

		default:
			return {};
	}
}

/** Get the data stored in a given cell of the table. */
QVariant KsViewModel::getValue(int column, int row) const
{
	return getValueStr(column, row);
}

/**
 * Get the header of a column. This is an implementation of the pure virtual
 * method of the abstract model class.
 */
QVariant KsViewModel::headerData(int column,
				 Qt::Orientation orientation,
				 int role) const
{
	if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
		return {};

	if (column < _header.count())
		return _header.at(column);

	return {};
}

/** Provide the model with data. */
void KsViewModel::fill(KsDataStore *data)
{
	beginInsertRows(QModelIndex(), 0, data->size() - 1);

	_data = data->rows();
	_nRows = data->size();
	_streamColors = KsPlot::streamColorTable();

	endInsertRows();
	_updateHeader();
}

/** @brief Select a row in the table.
 *
 * @param state: Identifier of the marker used to select the row.
 * @param row: Row index.
 */
void KsViewModel::selectRow(DualMarkerState state, int row)
{
	if (state == DualMarkerState::A) {
		_markA = row;
		_markB = KS_NO_ROW_SELECTED;
	} else {
		_markB = row;
		_markA = KS_NO_ROW_SELECTED;
	}
}

/** Reset the model. */
void KsViewModel::reset()
{
	beginResetModel();

	_data = nullptr;
	_nRows = 0;

	endResetModel();
}

/** Update the model. Use this function if the data has changed. */
void KsViewModel::update(KsDataStore *data)
{
	/*
	 * Do not try to skip the reset(). The row count has to be set to
	 * zero before you full.
	 */
	reset();
	fill(data);
}

/** Update the color scheme used by the model. */
void KsViewModel::loadColors()
{
	beginResetModel();
	_streamColors = KsPlot::streamColorTable();
	endResetModel();
}

/** @brief Search the content of the table for a data satisfying an abstract
 *	   condition.
 *
 * @param column: The number of the column to search in.
 * @param searchText: The text to search for.
 * @param cond: Matching condition function.
 * @param matchList: Output location for a list containing the row indexes of
 *		     the cells satisfying the matching condition.
 *
 * @returns The number of cells satisfying the matching condition.
 */
size_t KsViewModel::search(int column,
			   const QString &searchText,
			   search_condition_func cond,
			   QList<size_t> *matchList)
{
	int nRows = rowCount({});
	QVariant item;

	for (int r = 0; r < nRows; ++r) {
		item = getValue(r, column);
		if (cond(searchText, item.toString())) {
			matchList->append(r);
		}
	}

	return matchList->count();
}

/** @brief Reimplements handler to return a flags that enables the item
 *	   (ItemIsEnabled) and allows it to be selecte.
 *
 * @param index: The index of the item.
 *
 * @returns Returns the item flags for the given index.
 */
Qt::ItemFlags KsViewModel::flags(const QModelIndex &index) const {
	if (!index.isValid())
	    return Qt::ItemIsEnabled;

	return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}

/** Create a default (empty) KsFilterProxyModel object. */
KsGraphModel::KsGraphModel(QObject *parent)
: QAbstractTableModel(parent)
{
	ksmodel_init(&_histo);
}

/** Destroy KsFilterProxyModel object. */
KsGraphModel::~KsGraphModel()
{
	ksmodel_clear(&_histo);
}

/**
 * @brief Provide the Visualization model with data. Calculate the current
 *	  state of the model.
 */
void KsGraphModel::fill(KsDataStore *data)
{
	kshark_entry **entries = data->rows();
	size_t n = data->size();

	if (n == 0)
		return;

	beginResetModel();

	if (_histo.n_bins == 0)
		ksmodel_set_bining(&_histo,
				   KS_DEFAULT_NBUNS,
				   entries[0]->ts,
				   entries[n - 1]->ts);

	ksmodel_fill(&_histo, entries, n);

	endResetModel();
}

/**
 * @brief Shift the time-window of the model forward. Recalculate the current
 *	  state of the model.
 *
 * @param n: Number of bins to shift.
 */
void KsGraphModel::shiftForward(size_t n)
{
	beginResetModel();
	ksmodel_shift_forward(&_histo, n);
	endResetModel();
}

/**
 * @brief Shift the time-window of the model backward. Recalculate the current
 *	  state of the model.
 *
 * @param n: Number of bins to shift.
 */
void KsGraphModel::shiftBackward(size_t n)
{
	beginResetModel();
	ksmodel_shift_backward(&_histo, n);
	endResetModel();
}

/**
 * @brief Move the time-window of the model to a given location. Recalculate
 *	  the current state of the model.
 *
 * @param ts: position in time to be visualized.
 */
void KsGraphModel::jumpTo(size_t ts)
{
	beginResetModel();
	ksmodel_jump_to(&_histo, ts);
	endResetModel();
}

/**
 * @brief Extend the time-window of the model. Recalculate the current state
 *	  of the model.
 *
 * @param r: Scale factor of the zoom-out.
 * @param mark: Focus point of the zoom-out.
 */
void KsGraphModel::zoomOut(double r, int mark)
{
	beginResetModel();
	ksmodel_zoom_out(&_histo, r, mark);
	endResetModel();
}

/**
 * @brief Shrink the time-window of the model. Recalculate the current state
 *	  of the model.
 *
 * @param r: Scale factor of the zoom-in.
 * @param mark: Focus point of the zoom-in.
 */
void KsGraphModel::zoomIn(double r, int mark)
{
	beginResetModel();
	ksmodel_zoom_in(&_histo, r, mark);
	endResetModel();
}

/** Quick zoom out. The entire data-set will be visualized. */
void KsGraphModel::quickZoomOut()
{
	beginResetModel();

	ksmodel_set_bining(&_histo,
			   _histo.n_bins,
			   _histo.data[0]->ts,
			   _histo.data[_histo.data_size - 1]->ts);

	ksmodel_fill(&_histo, _histo.data, _histo.data_size);

	endResetModel();
}

/**
 * @brief Quick zoom in to a state of the Visualization model which has the
 * given bin size. The actual value of the bin size may en up being slightly
 * different because of the fine tuning performed by the model.
 *
 * @param binSize: an approximate value for the new size of the bins.
 */
void KsGraphModel::quickZoomIn(uint64_t binSize)
{
	double range, r;

	range =  _histo.max - _histo.min;
	r = 1 - (binSize * _histo.n_bins) / range;
	zoomIn(r);
}

/** Reset the model. */
void KsGraphModel::reset()
{
	beginResetModel();
	ksmodel_clear(&_histo);
	endResetModel();
}

/** Update the model. Use this function if the data has changed. */
void KsGraphModel::update(KsDataStore *data)
{
	beginResetModel();
	if (data)
		ksmodel_fill(&_histo, data->rows(), data->size());
	endResetModel();
}
