package tudelft.mentalhealth.motivatepersisting;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import tudelft.utilities.statistic.WeightedSet;
/**
* contains Table 1/ Statements-nl-NL.csv or Statements=en.csv: the Statements
* table with all available statements. The .csv files contain rows with 4
* columns of data:
*
* - New Category
*
- New subcat
*
- Count
*
- Statement (correct language)
*
*/
class Statements {
// contains for each Category and Subcategory a set of statements.
private final Map>> statements;
private static final Random random = new Random();
public Statements(Locale locale) {
statements = readTable(locale);
}
/**
*
* @param cat required {@link Category}
* @param subcat required {@link Subcategory}
* @return all statements for given category and subcategory.
*/
public WeightedSet getStatements(Category cat, Subcategory subcat) {
return statements.get(cat).get(subcat);
}
/**
* read in the CSV table
*
* @return map containing the CSV file contents.
* @throws IOException
*/
private Map>> readTable(
Locale locale) {
Map>> table = new HashMap<>();
String filename = "Statements-" + locale.toLanguageTag() + ".csv";
InputStream is = getClass().getResourceAsStream(filename);
if (is == null) {
throw new IllegalStateException("Resource not found: " + filename);
}
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
reader.lines().forEach(line -> addLine(line, table));
return table;
}
/**
* Add one line of comma-separated text (typically from csv file) to given
* table.
*
* @param line the line of text, containing Category, Subcategory, text.
* @param table the table to add the info in the line to
*/
private void addLine(String line,
Map>> table) {
String[] values = line.split(",", 4);
Category cat = Category.valueOf(values[0]);
Subcategory subcat;
if (values[1].isEmpty()) {
subcat = Subcategory.ALL;
if (!cat.getSubCategories().isEmpty()) {
throw new IllegalArgumentException("Category " + cat
+ " has subcategories, so ALL is not allowed in this table here:"
+ line);
}
} else {
subcat = Subcategory.valueOf(values[1]);
if (!cat.isSubcategoryAllowed(subcat)) {
throw new IllegalArgumentException(
"" + subcat + " is not allowed as subcategory of " + cat
+ " here :" + line);
}
}
if (!table.containsKey(cat)) {
table.put(cat, new HashMap<>());
}
WeightedSet map = table.get(cat).get(subcat);
Double count;
try {
count = Double.valueOf(values[2]);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("'" + values[2]
+ "' is not a good line count value here :" + line);
}
if (map != null) {
map = map.add(values[3].trim(), count);
} else {
Map first = new HashMap<>();
first.put(values[3].trim(), count);
map = new WeightedSet(first);
}
table.get(cat).put(subcat, map);
}
/**
* @param category the {@link Category} required
* @param subcategory the subcategory, or {@link Subcategory#ALL} if the
* category has no subcategory.
* @return text string that matches the Category and Subcategory as
* specified. Thee chosen text is weighted according to the count
* field of the text lines. Subsequent calls may return different
* results.
*/
public String getText(Category category, Subcategory subcategory) {
return getStatements(category, subcategory).getRandom();
}
}