package org.etsi.common;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

public class InputInterface {
	//TODO: can be transformed to static
	
	private String projectExt = "t3p";
	private String extRegExp = "ttcn|ttcn3";
	private boolean recursive = true;

	public InputInterface(String resourceExtRegExp, boolean recursive){
		this.extRegExp = resourceExtRegExp;
		this.recursive = recursive;
	}

	
	public InputInterface(String resourceExtRegExp, String projectExt, boolean recursive){
		this.extRegExp = resourceExtRegExp;
		this.projectExt = projectExt;
		this.recursive = recursive;
	}
	
	public void setExtRegExp(String extRegExp) {
		this.extRegExp = extRegExp;
	}

	public String getExtRegExp() {
		return extRegExp;
	}

	public void setRecursive(boolean recursive) {
		this.recursive = recursive;
	}

	public boolean isRecursive() {
		return recursive;
	}
	
	public List<String> inputFromFile(String filename){
		List<String> files = new LinkedList<String>();
		File file = new File(filename);
		if (file.isFile() && ExtensionFilter.checkFileExtension(file, extRegExp)){
			files.add(file.getPath());
		}
		return files;
	}

	public List<String> inputFromDirectory(String directory){
		List<String> files = new LinkedList<String>();
		File inputDir = new File(directory);
		File[] fileList = inputDir.listFiles(new ExtensionFilter(this.getExtRegExp()));

		for (int i = 0; i < fileList.length; i++) {
			files.add(fileList[i].getPath());
		}

		File[] dirList = inputDir.listFiles(new FileFilter() {
			public boolean accept(File pathname) {
				if (pathname.isDirectory())
					return true;
				return false;
			}
		});

		if (this.isRecursive()){
			for (int i = 0; i < dirList.length; i++) {
				files.addAll(inputFromDirectory(dirList[i].getPath()));
			}
		}
		
		return files;
	}

	public List<String> inputFromWildcard(String wildcard){
		List<String> files = new LinkedList<String>();
		File wildcardFile = new File(wildcard);
		System.out.println("Expanding wildcard \""+wildcard+"\"...");
		File wildcardParentFile = wildcardFile.getParentFile();
		if (wildcardParentFile == null) {
			wildcardParentFile = new File(".");
		}
		//TODO: needs to check if it is null and handle the situation
		if (wildcardParentFile.isDirectory()){
			File[] fileList = wildcardParentFile.listFiles(new WildcardFilter(wildcardFile));
			for (int i = 0; i < fileList.length; i++) {
				System.out.println("      ->"+fileList[i].getPath());
				files.addAll(this.getInputFromParameter(fileList[i].getPath()));
			}
		} else {
			//invalid parent directory, return
		}
		if (files.isEmpty()) {
			System.out.println("      ->No files found!");
		}
		return files;
	}

	public List<String> inputFromProject(String projectFilename){
		List<String> files = new LinkedList<String>();
		System.out.println("Reading input files from project file \""+projectFilename+"\"...");
		//TODO: Fill with content
		String projectFile = MiscTools.readFile(projectFilename);
		String[] lines = projectFile.split("\n");
		for (String line : lines) {
			if (!line.matches("\\s*")) {//.equals("")) {
				System.out.println("  "+line);
				files.addAll(this.getInputFromParameter(line));
			}
		}
		return files;
	}

	public void addToProject(List<String> files, String projectFilename){
		//TODO: Fill with content		
	}
	
	//TODO: this will make other duplicate checks obsolete
	public static List<String> filterAbsoluteDuplicates(List<String> inputFiles) {
		List<String> filteredInputFiles = new LinkedList<String>();
		List<String> absolutePaths = new LinkedList<String>();
		for (String inputFile : inputFiles) {
			try {
				String canonicalPath = new File(inputFile).getCanonicalPath();
				if (!absolutePaths.contains(canonicalPath)) {
					absolutePaths.add(canonicalPath);
					filteredInputFiles.add(inputFile);
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return filteredInputFiles;
	}
	
	//TODO: review, may be superfluous
	public List<String> getInputFromParameterList(List<String> parameters) {
		List<String> inputFiles = new LinkedList<String>();
		for (int i = 0; i < parameters.size(); i++) {
			List<String> fileList = getInputFromParameter(parameters.get(i));
			for (int f = 0; f < fileList.size(); f++) {
				String filename = fileList.get(f);
				if (!inputFiles.contains(filename)) {
					inputFiles.add(filename);
				} else {
					System.out.println("Entry \"" + filename
							+ "\" already present in the list, skipping..");
				}
			}
		}
		return inputFiles;
	}

	
	public List<String> getInputFromParameter(String inputParameter){
		List<String> inputFiles = new LinkedList<String>();
		File inputParameterFile = new File(inputParameter.trim());
		if (inputParameterFile.isDirectory()){
			if (this.isRecursive()){
				System.out.println("Collecting ttcn3 files recursively in \""
						+ inputParameter + "\" ...");
			} else {
				System.out.println("Collecting ttcn3 files non-recursively in \""
						+ inputParameter + "\" ...");
			}
			inputFiles = inputFromDirectory(inputParameter);
		} else {
			if (inputParameterFile.isFile()){
				if (inputParameterFile.getName().endsWith("."+projectExt)){
					inputFiles = inputFromProject(inputParameter);
				} else {
					inputFiles = inputFromFile(inputParameter);
				}
			} else {
				inputFiles = inputFromWildcard(inputParameter);
			}
		}
		return inputFiles;
	}

}
