package workerthreads.fitnessescriptcorrector;

import gui.MainFrameController;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.swing.SwingWorker;

import logging.Log;
import logging.LogLevel;
import tools.file.FileTool;
import tools.file.RecursiveFileListing;
import data.Settings;

/**
 * Worker-Class to change dates in fitnesse scripts.
 * 
 * @author Martin Pabst, 2009
 * 
 */
public class FitnesseScriptCorrector extends SwingWorker<Void, String> {

	/**
	 * store controller object
	 */
	private MainFrameController controller;

	/**
	 * constructor, only stores controller
	 * 
	 * @param controller
	 */
	public FitnesseScriptCorrector(MainFrameController controller) {
		super();
		this.controller = controller;

	}

	@Override
	protected Void doInBackground() throws Exception {
		controller.setButtonsEnabled(false);
		controller.setWaitCursor(true);
		controller.enableProgressbar(true);
		controller.setProgressBarMaximum(-1);

		/**
		 * get all fitnesse-files which should get examined
		 */
		List<File> fileList = RecursiveFileListing.getRecursiveFileList(
				Settings.getFitnesseRoot(), "txt", false, ".svn");

		Log.outl("" + fileList.size() + " Fitnesse-Dateien gefunden.\n",
				LogLevel.useful);

		Log.setProgressBarMaximum(fileList.size());

		/**
		 * do the actual work:
		 */
		correctFiles(fileList);

		// for (File file : fileList) {
		// Log.outl(file.getAbsolutePath(), LogLevel.useful);
		// }

		controller.setWaitCursor(false);
		controller.setButtonsEnabled(true);
		controller.enableProgressbar(false);

		return null;
	}

	/**
	 * change dates in given fitnesse-files
	 * 
	 * @param files
	 */
	private void correctFiles(List<File> files) {

		/**
		 * debug = true prints out files as token list,
		 */
		boolean debug = false;

		int i = 0;
		boolean firstFileInProtocoll = true;
		int countModified = 0; // number of modified files

		File protocollFile = null;

		if (Settings.getFitnesseProtocoll() != null) {
			protocollFile = new File(Settings.getFitnesseProtocoll());
		}

		for (File file : files) {

			Log.setProgressBarValue(i, file.getAbsolutePath());

			String textAlt;
			try {
				textAlt = FileTool.readTextFile(file, "UTF-8");
				Lexer l = new Lexer();
				TokenList tokenList = l.lex(textAlt);

				if (debug) {
					testOutput(file, textAlt, tokenList);
				}

				FitnesseTimeMachine tm = new FitnesseTimeMachine(tokenList,
						Settings.getFitnesseDestinationSchoolyear());

				boolean modified = tm.run();

				if (modified) {
					countModified++;
					Log.outlColor(
							file.getAbsolutePath()
									+ " geändert von "
									+ intToSchuljahrString(tm
											.getOldBaseSchoolyear())
									+ " nach "
									+ intToSchuljahrString(Settings
											.getFitnesseDestinationSchoolyear())
									+ ".", LogLevel.useful,
							new Color(0, 100, 0));
				} else {
					Log.outlColor(file.getAbsolutePath() + " nicht geändert.",
							LogLevel.useful, Color.blue);
				}

				if (debug) {
					Log.outlColor("\n\nNeue Version:", LogLevel.useful,
							new Color(0, 0, 100));

					Log.outl(tokenList.toString(), LogLevel.useful);

				}

				if (modified) {
					String textNeu = tokenList.toString();

					if (Settings.getFitnesseProtocoll() != null) {
						String s = "File " + file.getAbsolutePath() + ": \n";
						s += "\r\n========== Alt: ==========\r\n";
						s += textAlt;

						s += "\r\n========== Neu: ==========\r\n";
						s += textNeu;

						s += "\r\n========== Tokens: ============\r\n";
						s += tokenList.traceOutput();

						FileTool.writeTextFile(protocollFile, "UTF-8", s,
								!firstFileInProtocoll);

						firstFileInProtocoll = false;

						if (Settings.isFitnesseWriteChanges()) {
							FileTool.writeTextFile(file, "UTF-8", textNeu,
									false);
						}

					}

				}

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			i++;

			// if (i == 1) {
			// break;
			// }

		}

		Log.outlColor("\n\n" + countModified + " files altered. ",
				LogLevel.useful, Color.blue);

	}

	private String intToSchuljahrString(int sj) {
		int sjp1 = (sj + 1) % 100;
		return sj + "/" + (sjp1 < 10 ? "0" : "") + sjp1;
	}

	private void testOutput(File file, String text, TokenList tokenList) {
		Log.outlColor("\n" + file.getAbsolutePath(), LogLevel.useful,
				Color.blue);
		Log.outlColor(text, LogLevel.useful, Color.black);
		Log.outlColor(tokenList.traceOutput(), LogLevel.useful, new Color(0,
				100, 0));
	}

}
