package org.eclipse.ganymede.webgen;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/*
 * Status file format:
 * [0] status keyword
 * [1] status color
 * [2] status descriptive string
 * [3] start time
 * [4] end time
 * [5] end time as a directory name
 * [6] first error bookmark
 * [7] emails addresses for failure notification
 */
public class GenerateStatusFile {
	public static void main(String[] args) throws IOException {
		(new GenerateStatusFile(new File(args[0]))).write_begin_status_file();
	}

	File directory;
	String keyword;
	String color;
	String description;
	public String start_time;
	public String end_time;
	public String end_time_dir;
	String error_bookmark;
	String email_addresses;

	static SimpleDateFormat df;

	public GenerateStatusFile(File directory) {
		this.directory = directory;
		try {
			this.read();
		} catch (IOException x) {
			this.keyword = "UNKNOWN";
			this.color = WebPageColors.fail_color();
			this.description = "?????";
		}
		if( df == null ) {
			df = (SimpleDateFormat) DateFormat.getDateTimeInstance();
			df.applyPattern("MMM d, yyyy HH:mm:ss z");
		}
	}

	void write_begin_status_file() throws IOException {
		this.keyword = "INPROGRESS";
		this.color = WebPageColors.inprogress_color();
		this.description = "in progress";
		this.start_time = df.format(new Date());
		this.mark_end_time(); // makes a valid end_time_dir so that this build
								// is properly added to the recent directory if
								// it crashes
		this.end_time = ""; // but we reset the actual end time because this
							// build is in progress
		this.error_bookmark = "";
		this.email_addresses = "";
		this.write();
	}

	void mark_end_time() {
		Date now = new Date();
		this.end_time = df.format(now);
		Calendar cal = df.getCalendar();
		this.end_time_dir = cal.get(Calendar.YEAR) + "_"
				+ threedigits(cal.get(Calendar.DAY_OF_YEAR)) + "_"
				+ twodigits(cal.get(Calendar.HOUR_OF_DAY)) + "_"
				+ twodigits(cal.get(Calendar.MINUTE)) + "_"
				+ twodigits(cal.get(Calendar.SECOND));
	}

	private String twodigits(int v) {
		if (v < 10)
			return "0" + v;
		else
			return "" + v;
	}
	
	private String threedigits(int v) {
		if (v < 10)
			return "00" + v;
		else if (v < 100)
			return "0" + v;
		else
			return "" + v;
	}

	private void write() throws IOException {
		File fout = new File(this.directory, "status.txt");
		PrintWriter w = new PrintWriter(new FileWriter(fout));
		w.println(this.keyword);
		w.println(this.color);
		w.println(this.description);
		w.println(this.start_time);
		w.println(this.end_time);
		w.println(this.end_time_dir);
		w.println(this.error_bookmark);
		w.println(this.email_addresses);
		w.close();
	}

	private void read() throws IOException {
		File fin = new File(this.directory, "status.txt");
		BufferedReader r = new BufferedReader(new FileReader(fin));
		this.keyword = r.readLine();
		this.color = r.readLine();
		this.description = r.readLine();
		this.start_time = r.readLine();
		this.end_time = r.readLine();
		this.end_time_dir = r.readLine();
		this.error_bookmark = r.readLine();
		this.email_addresses = r.readLine();
	}

	void write_internal_error_status_file(Exception x) throws IOException {
		this.keyword = "FAIL";
		this.color = WebPageColors.fail_color();
		this.description = "internal error " + x.toString();
		this.mark_end_time();
		this.write();
	}

	void write_final_status_file(Status status) throws IOException {
		this.keyword = "UNKNOWN";
		if (status.isSuccess())
			this.keyword = "SUCCESS";
		if (status.isFail())
			this.keyword = "FAIL";
		this.color = status.color();
		this.description = status.toString();
		this.error_bookmark = status.error_bookmark;
		this.email_addresses = status.getFailureEmailAddressesString();
		this.write();
	}
}
