package org.etsi.common;

import java.io.BufferedWriter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.etsi.common.exceptions.TerminationException;


public class MiscTools {

	//TODO: Add exceptions and throws declarations
	public static String readFile(String filename) {
		FileInputStream fis;
		String content = "";
		try {
			fis = new FileInputStream(filename);
			int x = fis.available();
			byte b[] = new byte[x];
			fis.read(b);
			content = new String(b);
		} catch (FileNotFoundException e) {
			String message = "IO ERROR: Filename "+filename+" cannot be found for reading!";
			try {
				throw new TerminationException(message);
			} catch (TerminationException e1) {
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return content;
	}

	public static String getShortFilename(String filename) {
		String shortfilename = new File(filename).getName();
		return shortfilename;
	}

	public static String getMethodName(){
		return Thread.currentThread().getStackTrace()[2].getMethodName();
	}
	
	
	public static void writeFile(String filename, String content) {
		FileOutputStream fos;
		File targetDir = new File(filename).getAbsoluteFile().getParentFile();
		try {
			if (!targetDir.exists()) {
				if (!targetDir.mkdirs()) {
					System.out
							.println("IO ERROR: Creating the directory structure for \""
									+ filename + "\" failed!");
				}
			}

			try {
				fos = new FileOutputStream(filename);
				Writer w = new BufferedWriter(new OutputStreamWriter(fos));
				w.write(content);
				w.flush();
				w.close();
							
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (SecurityException se) {
			System.out
					.println("IO ERROR: Could not create ouput files and / or directories!"
							+ "Caused by: \"" + filename + "\"");
		}

	}

	public static void streamCopyFile(String sourceFilename, String targetFilename){
		try {
			File targetFile = new File(targetFilename);
			if (!targetFile.getParentFile().exists()){
				if (!targetFile.getParentFile().mkdirs()){
					System.out
					.println("IO ERROR: Creating the directory structure for \""
							+ targetFilename + "\" failed!");
				}
			}
			FileOutputStream outStream = new FileOutputStream(targetFile);
			FileInputStream inStream = new FileInputStream(sourceFilename);
			int c;
			try {
				while((c = inStream.read()) != -1){
					outStream.write(c);
				}	
			} catch (IOException e) {
				System.out.println("IO ERROR: Caused while copying: \""+sourceFilename+"\" to \""+targetFilename+"\"");
			}
		} catch (FileNotFoundException e1) {
			System.out.println("IO ERROR: File not found: \""+sourceFilename+" / "+targetFilename+"\"");
			e1.printStackTrace();
		}
	}
	
//	public static String getSubPath(String basePath, String resourcePath) {
//		String subPath = resourcePath.substring(basePath.length());
//		return subPath;
//	}
	
	// --------------------------------------------------------------------------

	public static int getLOC(String filename){
		String code = MiscTools.readFile(filename);
		int LOC = code.split("\n").length;
		return LOC;
	}

	// --------------------------------------------------------------------------
	public static String doubleToString(double d) {
		DecimalFormat fmt = new DecimalFormat("0.00");
		String string = fmt.format(d);
		return string;
	}

	public static String getSubPath(String inputPath){
		String subPath = "";
		File input = new File(getProperInputPath(inputPath));
		if (input.isFile()){
			subPath = input.getName().substring(0, input.getName().lastIndexOf("."));
		} else {
			subPath = input.getName();
		}
		return subPath;
	}

	public static String getProperOutputPath(String outputDirectory) {
		String properOutputPath = "";
		try {
			//gets the full path if relative path is provided
			properOutputPath = new File(outputDirectory).getCanonicalPath();
		} catch (IOException e) {
			System.out.println("IO ERROR: ");
			e.printStackTrace();
		} 
		return properOutputPath;
	}

	public static String getProperInputPath(String inputPath) {
		// strips slash if present
		//TODO: reorganize and extrarct
		//TODO: Document "feature" -> if multiple input paths are provided, the first one will be used for the sub path calculation
		String properInputPath = new File(inputPath).getPath();
		
		if (properInputPath.equals(".")) {
			try {
				//gets the full path
				properInputPath = new File(properInputPath).getCanonicalFile()
						.getName();
			} catch (IOException e) {
				System.out.println("IO ERROR: ");
				e.printStackTrace();
			}
		}
		return properInputPath;
	}

	//TODO: cloned from NamingConventionsChecker => needs to be unified and reused
	//note: if regExp is not set it defaults to false quietly
	public static boolean regExpMatch(String regExp, String subject) {
		boolean matches = false;
		if (regExp!=null){
			Pattern pattern = Pattern.compile(regExp);
			Matcher matcher = pattern.matcher(subject);
	//		System.out.println(regExp + " : " + subject);
			if (matcher.matches()) {
				matches = true;
			}
		}
		return matches;
	}
}
