#ifndef ENGINE_HPP
#define ENGINE_HPP

#include <cstdlib>
#include <list>
#include <regex>
#include <string>

struct Result {
   Result(std::size_t rline_no, const char* line, std::size_t len) :
	 rline_no(rline_no), line(line), len(len) {
   }
   std::size_t rline_no; // relative line number
   const char* line; // pointer to the begin of the corresponding line
   std::size_t len; // length of the line excluding the line terminator
};

class Engine {
   public:
      Engine() : start(nullptr), len(0), lines(0) {
      }
      void configure(const char* start, std::size_t len) {
	 this->start = start; this->len = len; lines = 0;
      }
      void search(const std::regex re) {
	 const char* current_line = start; /* begin of current line */
	 lines = 0; /* number of complete lines seen so far */
	 
	 for (const char* cp = start; cp < start + len; ++cp) {
	    if (*cp == '\n') {
	       if (std::regex_search(current_line, cp, re)) {
		  results.push_back(Result(lines, current_line,
		     cp - current_line));
	       }
	       ++lines;
	       current_line = cp + 1;
	    }
	 }
      }
      auto fetch_results() {
	 return std::move(results);
      }
      std::size_t get_number_of_lines() const {
	 return lines;
      }
   private:
      const char* start; /* begin of our memory area */
      std::size_t len; /* length of our memory area in bytes */
      std::size_t lines; /* number of lines within [start, start+len) */
      std::list<Result> results;
};

#endif
