
#include "table.h"

namespace usql {

Table::Table(const std::string name, const std::vector<ColDefNode> columns) {
	m_name = name;
	m_col_defs = columns;
	m_rows.clear();
}

ColDefNode Table::get_column_def(const std::string &col_name) {
	auto name_cmp = [col_name](ColDefNode cd) { return cd.name == col_name; };
	auto col_def = std::find_if(begin(m_col_defs), end(m_col_defs), name_cmp);
	if (col_def != std::end(m_col_defs)) {
		return *col_def;
	} else {
		throw Exception("column not exists (" + col_name + ")");
	}
}


Row Table::createEmptyRow() {
	return Row(columns_count());
}


void Table::print() {
	std::cout << "** " << m_name << " **" << std::endl;
	for (auto row : m_rows) {
		row.print();
	}
}

Table::Table(const Table &other) {
	m_name = other.m_name;
	m_col_defs = other.m_col_defs;
	for(const Row& orig_row : other.m_rows) {
		addCopyOfRow(orig_row);
	}
}

void Table::addRow(const Row &row) {
	// TODO validate for not null values
	// todo validate for length etc
	m_rows.push_back(row);
}

void Table::addCopyOfRow(const Row &row) {
	// TODO validate for not null values
	// todo validate for length etc

	Row new_row = createEmptyRow();

	for(int i = 0; i < m_col_defs.size(); i++) {
		ColValue *ct = row.ithColumn(i);

		if (ct->isNull()) {
			new_row.setColumnNull(i);
		} else {
			if (m_col_defs[i].type == ColumnType::integer_type) {
				new_row.setColumnValue(i, row.ithColumn(i)->getIntValue());
			} else if (m_col_defs[i].type == ColumnType::float_type) {
				new_row.setColumnValue(i, row.ithColumn(i)->getDoubleValue());
			} else if (m_col_defs[i].type == ColumnType::varchar_type) {
				new_row.setColumnValue(i, row.ithColumn(i)->getStringValue());
			}
		}
	}
	m_rows.push_back(row);
}

}	// namespace