#include "CSVReader.h"
#include <iostream>
#include <cstdlib>

namespace math1d_cl
{
	CSVReader::CSVReader(char decimal,char separator) : m_decimal(decimal), m_separator(separator)
	{
		m_header = std::make_shared<std::vector<std::string>>();
	}

	void CSVReader::open(std::string file)
	{
		m_fileStream.open(file, std::ifstream::in);
		if(m_fileStream.fail())
		{
			std::cerr << "ERROR: Failed to open file " << file << std::endl;
			close();
			std::exit(-1);
		} else {
			// Parse header
			if(!eof())
			{
				std::locale loc("");
				m_fileStream.imbue(loc);
				std::string head;
				std::getline(m_fileStream, head);
				explode(head, m_header, m_separator);
			} else
			{
				std::cerr << "ERROR: Empty file." << std::endl;
				close();
				std::exit(-1);
			}
		}
	}

	void CSVReader::close()
	{
		m_fileStream.close();
	}

	std::shared_ptr<std::vector<std::string>> CSVReader::getHeader()
	{
		return m_header;
	}

	std::shared_ptr<std::vector<std::string>> CSVReader::getRow()
	{
		std::shared_ptr<std::vector<std::string>> row = std::make_shared<std::vector<std::string>>();
		if(!eof())
		{
			std::string line;
			std::getline(m_fileStream, line);
			if(line.size() > 0) // Skip empty lines
			{
				explode(line, row, m_separator);
				if(row->size() != m_header->size())
				{
					std::cerr << "CSVReader ERROR: Column count not equal header column count" << std::endl;
					close();
					std::exit(-1);
				}
			}
		}
		return row;
	}

	void CSVReader::explode(std::string input, std::shared_ptr<std::vector<std::string>> output, const char delimiter)
	{
		std::string buffer;
		for(std::string::const_iterator it = input.begin(); it != input.end(); ++it)
		{
			if(*it == delimiter)
			{
				output->push_back(buffer);
				buffer.clear();
			} else {
				buffer.push_back(*it);
			}
		}
		
		if(buffer != "") output->push_back(buffer);
		buffer.clear();
	}

	bool CSVReader::eof()
	{
		return m_fileStream.eof();
	}


}