#include <libwccl/values/match.h>
#include <libwccl/ops/match/actions/unmarkmatch.h>
#include <libcorpus2/ann/annotatedsentence.h>

#include <sstream>

namespace Wccl {

void UnmarkMatch::execute(const ActionExecContext& context) const
{
	SentenceContext& sc = context.sentence_context();
	boost::shared_ptr<Corpus2::AnnotatedSentence> as;
	as = boost::dynamic_pointer_cast<Corpus2::AnnotatedSentence>(sc.get_sentence_ptr());
	if (!as) {
		throw InvalidArgument("context", "Operator needs an annotated sentence.");
	}
	if (!as->has_channel(chan_name_)) {
		throw InvalidArgument("context", "Sentence does not have annotation channel \"" + chan_name_ + "\".");
	}

	int abs_pos = match_->apply(context)->first_token(as).get_value();
	if(sc.is_outside(abs_pos)) {
		throw WcclError("Received starting match that points outside sentence.");
	}

	Corpus2::AnnotationChannel& channel = as->get_channel(chan_name_);

	int segment_idx = channel.get_segment_at(abs_pos);
	if (segment_idx == 0) {
		throw WcclError("No annotation \"" + chan_name_ + "\" to delete at the specified position.");
	}

	for (int i = 0; i < channel.size(); ++i) {
		if (channel.segments()[i] == segment_idx) {
			channel.set_segment_at(i, 0);
		}
	}
}

std::string UnmarkMatch::to_string(const Corpus2::Tagset& tagset) const
{
	std::ostringstream os;
	os << name() << "(" << match_->to_string(tagset) << ", \"" << chan_name_ << "\")";
	return os.str();
}

std::ostream& UnmarkMatch::write_to(std::ostream& os) const
{
	return os << name() << "(" << *match_ << ", \"" << chan_name_ << "\")";
}

} /* end ns Wccl */