package de.tudresden.inf.lat.tabula.main;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;

import de.tudresden.inf.lat.tabula.datatype.CompositeType;
import de.tudresden.inf.lat.tabula.datatype.CompositeTypeImpl;
import de.tudresden.inf.lat.tabula.datatype.StringValue;
import de.tudresden.inf.lat.tabula.parser.SimpleFormatParser;
import de.tudresden.inf.lat.tabula.renderer.SimpleFormatRenderer;
import de.tudresden.inf.lat.tabula.table.Table;
import de.tudresden.inf.lat.tabula.table.TableImpl;
import de.tudresden.inf.lat.tabula.table.TableMap;
import de.tudresden.inf.lat.tabula.table.TableMapImpl;

/**
 * This is a test of modification of a Tabula file.
 */
public class MainTest {

	public static final String INPUT_FILE_NAME = "src/test/resources/example.properties";
	public static final String EXPECTED_OUTPUT_FILE_NAME = "src/test/resources/example-modified.properties";

	public static final String TYPE_NAME_RECORD = "record";
	public static final String FIELD_NAME_AUTHORS = "authors";
	public static final String FIELD_NAME_NUMBER_OF_AUTHORS = "numberOfAuthors";
	public static final String TYPE_OF_NUMBER_OF_AUTHORS = "String";
	public static final String NEW_LINE = "\n";

	@Test
	public void addNewFieldOldTest() throws IOException {

		// This is an example of source code where the number of authors is
		// a computed value

		// Read the table map
		TableMap oldTableMap = new SimpleFormatParser(new FileReader(INPUT_FILE_NAME)).parse();

		// Make a copy of the tableMap
		// TableMapImpl newTableMap = new TableMapImpl(oldTableMap);
		TableMapImpl newTableMap = new TableMapImpl();
		oldTableMap.getTableIds().forEach(tableId -> newTableMap.put(tableId, oldTableMap.getTable(tableId)));

		// Get the main table
		Table table = newTableMap.getTable(TYPE_NAME_RECORD);

		// Make a copy of the main table
		TableImpl newTable = new TableImpl(table);

		// Add the new table to the new table map
		newTableMap.put(TYPE_NAME_RECORD, newTable);

		// Get type of main table
		CompositeType oldType = table.getType();

		// Make a copy of type
		// CompositeTypeImpl newType = new CompositeTypeImpl(oldType);
		CompositeTypeImpl newType = new CompositeTypeImpl();
		oldType.getFields().forEach(field -> newType.declareField(field, oldType.getFieldType(field)));

		// Add new declaration with number of authors
		if (!newType.getFields().contains(FIELD_NAME_NUMBER_OF_AUTHORS)) {
			newType.declareField(FIELD_NAME_NUMBER_OF_AUTHORS, TYPE_OF_NUMBER_OF_AUTHORS);
		}

		// Update type of table
		newTable.setType(newType);

		// Compute the number of authors for each record
		table.getRecords().forEach(record -> {
			List<String> authors = record.get(FIELD_NAME_AUTHORS).renderAsList();
			int numberOfAuthors = authors.size();
			record.set(FIELD_NAME_NUMBER_OF_AUTHORS, new StringValue("" + numberOfAuthors));
		});

		// Store the new table map
		StringWriter writer = new StringWriter();
		SimpleFormatRenderer renderer = new SimpleFormatRenderer(writer);
		renderer.render(newTableMap);

		// Read the expected output
		StringBuffer sbuf = new StringBuffer();
		BufferedReader reader = new BufferedReader(new FileReader(EXPECTED_OUTPUT_FILE_NAME));
		reader.lines().forEach(line -> sbuf.append(line + NEW_LINE));
		reader.close();

		// Compare the expected output with the actual output
		Assert.assertEquals(sbuf.toString(), writer.toString());
	}

}

@@ -154,31 +154,8 @@
 ter;
-%0Aimport java.util.List;
 %0A%0Aim
@@ -319,24 +319,140 @@
 teTypeImpl;%0A
+import de.tudresden.inf.lat.tabula.datatype.PrimitiveTypeValue;%0Aimport de.tudresden.inf.lat.tabula.datatype.Record;%0A
 import de.tu
@@ -1417,16 +1417,392 @@
  %22%5Cn%22;%0A%0A
+%09/**%0A%09 * Returns the number of authors for a given record.%0A%09 * %0A%09 * @param record%0A%09 *            record%0A%09 * @return the number of authors for a given record%0A%09 */%0A%09StringValue computeFieldValue(Record record) %7B%0A%09%09PrimitiveTypeValue value = record.get(FIELD_NAME_AUTHORS);%0A%09%09int size = (value == null) ? 0 : value.renderAsList().size();%0A%09%09return new StringValue(%22%22 + size);%0A%09%7D%0A%0A
 %09@Test%0A%09
@@ -3239,127 +3239,8 @@
  -%3E 
-%7B%0A%09%09%09List%3CString%3E authors = record.get(FIELD_NAME_AUTHORS).renderAsList();%0A%09%09%09int numberOfAuthors = authors.size();%0A%09%09%09
 reco
@@ -3280,51 +3280,34 @@
 RS, 
-new StringValue(%22%22 + numberOfAuthors
+computeFieldValue(record
 ))
-;%0A%09%09%7D
 );%0A%0A

Update unit test