package com.concurrentperformance.traintimes.reporter;

import com.concurrentperformance.traintimes.extractor.TrainDetail;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Report to file to allow simple understanding of delays.
 *
 * @author Stephen
 */
public class FileTrainReporter implements ProblemTrainReporter {

	private final Logger log = LoggerFactory.getLogger(this.getClass());

	private DateTimeFormatter time = DateTimeFormat.forPattern("[HH:mm]");
	private TrainDetailFormatter formatter;
	private String rootDirectory;

	@Override
	public void reportDelays(String name, List<TrainDetail> problemTrains, Document originalDocument) {
		// Don;t want to create any directories for days when no problems.
		if (problemTrains.size() == 0) {
			return;
		}
		checkNotNull(rootDirectory);

		String delaysTextForFile = getDelayText(name, problemTrains);
		writeDelayFile(name, delaysTextForFile);

		// Writer the original HTML for reference.
		writeOriginalHTML(name, originalDocument);
	}

	private String getDelayText(String name, List<TrainDetail> problemTrains) {
		StringBuilder buff = new StringBuilder();

		// Write Time
		buff.append(time.print(LocalTime.now())).append(System.lineSeparator());

		//Write Trains
		for (TrainDetail problemTrain : problemTrains) {
			buff.append("  ").append(formatter.format(name, problemTrain)).append(System.lineSeparator());
		}

		return buff.toString();
	}

	private void writeDelayFile(String name, String delaysTextForFile) {
		try {
			Path directoryPath = getTodaysDatePath();
			Files.createDirectories(directoryPath);
			Path filePath = Paths.get(directoryPath.toString(), name + "_problems.txt");
			Files.write(filePath, delaysTextForFile.getBytes(),
					StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE);
		} catch (IOException e) {
			log.error("", e);
		}
	}

	private void writeOriginalHTML(String name, Document originalDocument) {
		try {
			Path directoryPath = getTodaysDatePath();
			String todaysTimeFormat = getTodaysTimeFormatForFile();
			Files.createDirectories(directoryPath);
			Path filePath = Paths.get(directoryPath.toString(), name + "_" + todaysTimeFormat + ".html");
			Files.write(filePath, originalDocument.html().getBytes(),
					StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW);
		} catch (IOException e) {
			log.error("", e);
		}
		originalDocument.html();

	}

	private Path getTodaysDatePath() throws IOException {
		String todaysDateFormat = getTodaysDateFormatForFile();
		Path directoryPath = Paths.get(rootDirectory, todaysDateFormat);
		return directoryPath;
	}

	public String getTodaysDateFormatForFile() {
		DateTimeFormatter dateFormatter = ISODateTimeFormat.yearMonthDay();
		String todaysDateFormat = dateFormatter.print(LocalDate.now());
		return todaysDateFormat;
	}

	public String getTodaysTimeFormatForFile() {
		DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("HH_mm");
		String timeNowFormat = timeFormatter.print(LocalTime.now());
		return timeNowFormat;
	}

	public void setRootDirectory(String rootDirectory) {
		this.rootDirectory = rootDirectory;
	}

	public void setFormatter(TrainDetailFormatter formatter) {
		this.formatter = formatter;
	}
}
