/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2023, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#include "apps-precomp.h"  // Precompiled headers
//
#include "rawlog-edit-declarations.h"

using namespace mrpt;
using namespace mrpt::obs;
using namespace mrpt::system;
using namespace mrpt::apps;
using namespace std;
using namespace mrpt::io;

// ======================================================================
//		op_remove_label
// ======================================================================
DECLARE_OP_FUNCTION(op_remove_label)
{
	// A class to do this operation:
	class CRawlogProcessor_RemoveLabel
		: public CRawlogProcessorFilterObservations
	{
	   protected:
		vector<string> m_filter_labels;

	   public:
		CRawlogProcessor_RemoveLabel(
			mrpt::io::CFileGZInputStream& in_rawlog, TCLAP::CmdLine& cmdline,
			bool _verbose, mrpt::io::CFileGZOutputStream& out_rawlog,
			const std::string& filter_label)
			: CRawlogProcessorFilterObservations(
				  in_rawlog, cmdline, _verbose, out_rawlog)
		{
			mrpt::system::tokenize(filter_label, " ,", m_filter_labels);
			ASSERT_(!m_filter_labels.empty());
			if (verbose)
				for (const auto& m_filter_label : m_filter_labels)
					cout << "Removing label: '" << m_filter_label << "'\n";
		}

		/** To be implemented by users: return false means the observation is */
		bool tellIfThisObsPasses(mrpt::obs::CObservation::Ptr& obs) override
		{
			for (const auto& m_filter_label : m_filter_labels)
				if (obs->sensorLabel == m_filter_label) { return false; }
			return true;
		}
	};

	// Process
	// ---------------------------------
	string filter_label;
	if (!getArgValue<string>(cmdline, "remove-label", filter_label) ||
		filter_label.empty())
		throw std::runtime_error(
			"remove-label: This operation needs a non-empty argument.");

	TOutputRawlogCreator outrawlog;
	CRawlogProcessor_RemoveLabel proc(
		in_rawlog, cmdline, verbose, outrawlog.out_rawlog_io, filter_label);
	proc.doProcessRawlog();

	// Dump statistics:
	// ---------------------------------
	VERBOSE_COUT << "Time to process file (sec)        : " << proc.m_timToParse
				 << "\n";
	VERBOSE_COUT << "Analyzed entries                  : "
				 << proc.m_entries_parsed << "\n";
	VERBOSE_COUT << "Removed entries                   : "
				 << proc.m_entries_removed << "\n";
}

// ======================================================================
//		op_keep_label
// ======================================================================
DECLARE_OP_FUNCTION(op_keep_label)
{
	// A class to do this operation:
	class CRawlogProcessor_KeepLabel : public CRawlogProcessorFilterObservations
	{
	   protected:
		vector<string> m_filter_labels;

	   public:
		CRawlogProcessor_KeepLabel(
			mrpt::io::CFileGZInputStream& in_rawlog, TCLAP::CmdLine& cmdline,
			bool _verbose, mrpt::io::CFileGZOutputStream& out_rawlog,
			const std::string& filter_label)
			: CRawlogProcessorFilterObservations(
				  in_rawlog, cmdline, _verbose, out_rawlog)
		{
			mrpt::system::tokenize(filter_label, " ,", m_filter_labels);
			ASSERT_(!m_filter_labels.empty());
			if (verbose)
				for (const auto& m_filter_label : m_filter_labels)
					cout << "Keeping label: '" << m_filter_label << "'\n";
		}

		/** To be implemented by users: return false means the observation is */
		bool tellIfThisObsPasses(mrpt::obs::CObservation::Ptr& obs) override
		{
			for (const auto& m_filter_label : m_filter_labels)
				if (obs->sensorLabel == m_filter_label) { return true; }
			return false;
		}
	};

	// Process
	// ---------------------------------
	string filter_label;
	if (!getArgValue<string>(cmdline, "keep-label", filter_label) ||
		filter_label.empty())
		throw std::runtime_error(
			"keep-label: This operation needs a non-empty argument.");

	TOutputRawlogCreator outrawlog;
	CRawlogProcessor_KeepLabel proc(
		in_rawlog, cmdline, verbose, outrawlog.out_rawlog_io, filter_label);
	proc.doProcessRawlog();

	// Dump statistics:
	// ---------------------------------
	VERBOSE_COUT << "Time to process file (sec)        : " << proc.m_timToParse
				 << "\n";
	VERBOSE_COUT << "Analyzed entries                  : "
				 << proc.m_entries_parsed << "\n";
	VERBOSE_COUT << "Removed entries                   : "
				 << proc.m_entries_removed << "\n";
}
