package aQute.lib.osgi;

import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.regex.*;

import aQute.lib.io.*;
import aQute.libg.sed.*;
import aQute.libg.version.*;

/**
 * Provide a macro processor. This processor can replace variables in strings
 * based on a properties and a domain. The domain can implement functions that
 * start with a "_" and take args[], the names of these functions are available
 * as functions in the macro processor (without the _). Macros can nest to any
 * depth but may not contain loops.
 * 
 * Add POSIX macros:
 * ${#parameter}
    String length.

${parameter%word}
    Remove smallest suffix pattern.

${parameter%%word}
    Remove largest suffix pattern.

${parameter#word}
    Remove smallest prefix pattern.

${parameter##word}
    Remove largest prefix pattern. 
 */
public class Macro implements Replacer {
	Processor	domain;
	Object		targets[];
	boolean		flattening;

	public Macro(Processor domain, Object... targets) {
		this.domain = domain;
		this.targets = targets;
		if (targets != null) {
			for (Object o : targets) {
				assert o != null;
			}
		}
	}

	public String process(String line, Processor source) {
		return process(line, new Link(source,null,line));
	}

	String process(String line, Link link) {
		StringBuffer sb = new StringBuffer();
		process(line, 0, '\u0000', '\u0000', sb, link);
		return sb.toString();
	}

	int process(CharSequence org, int index, char begin, char end, StringBuffer result, Link link) {
		StringBuilder line = new StringBuilder(org);
		int nesting = 1;

		StringBuffer variable = new StringBuffer();
		outer: while (index < line.length()) {
			char c1 = line.charAt(index++);
			if (c1 == end) {
				if (--nesting == 0) {
					result.append(replace(variable.toString(), link));
					return index;
				}
			} else if (c1 == begin)
				nesting++;
			else if (c1 == '\\' && index < line.length() - 1 && line.charAt(index) == '$') {
				// remove the escape backslash and interpret the dollar as a
				// literal
				index++;
				variable.append('$');
				continue outer;
			} else if (c1 == '$' && index < line.length() - 2) {
				char c2 = line.charAt(index);
				char terminator = getTerminator(c2);
				if (terminator != 0) {
					index = process(line, index + 1, c2, terminator, variable, link);
					continue outer;
				}
			}
			variable.append(c1);
		}
		result.append(variable);
		return index;
	}

	public static char getTerminator(char c) {
		switch (c) {
		case '(':
			return ')';
		case '[':
			return ']';
		case '{':
			return '}';
		case '<':
			return '>';
		case '\u00ab': // Guillemet double << >>
			return '\u00bb';
		case '\u2039': // Guillemet single
			return '\u203a';
		}
		return 0;
	}

	protected String replace(String key, Link link) {
		if (link != null && link.contains(key))
			return "${infinite:" + link.toString() + "}";

		if (key != null) {
			key = key.trim();
			if (key.length() > 0) {
				Processor source = domain;
				String value = null;
				while( source != null) {
					value = source.getProperties().getProperty(key);
					if ( value != null )
						break;
					
					source = source.getParent();
				}
				
				if (value != null)
					return process(value, new Link(source,link, key));

				value = doCommands(key, link);
				if (value != null)
					return process(value, new Link(source, link, key));

				if (key != null && key.trim().length() > 0) {
					value = System.getProperty(key);
					if (value != null)
						return value;
				}
				if (!flattening)
					domain.warning("No translation found for macro: " + key);
			} else {
				domain.warning("Found empty macro key");
			}
		} else {
			domain.warning("Found null macro key");
		}
		return "${" + key + "}";
	}

	/**
	 * Parse the key as a command. A command consist of parameters separated by
	 * ':'.
	 * 
	 * @param key
	 * @return
	 */
	static Pattern	commands	= Pattern.compile("(?<!\\\\);");

	private String doCommands(String key, Link source) {
		String[] args = commands.split(key);
		if (args == null || args.length == 0)
			return null;

		for (int i = 0; i < args.length; i++)
			if (args[i].indexOf('\\') >= 0)
				args[i] = args[i].replaceAll("\\\\;", ";");

		
		if ( args[0].startsWith("^")) {
			String varname = args[0].substring(1).trim();
			
			Processor parent = source.start.getParent();
			if ( parent != null)
				return parent.getProperty(varname);
			else
				return null;
		}
		
		
		Processor rover = domain;
		while (rover != null) {
			String result = doCommand(rover, args[0], args);
			if (result != null)
				return result;

			rover = rover.getParent();
		}

		for (int i = 0; targets != null && i < targets.length; i++) {
			String result = doCommand(targets[i], args[0], args);
			if (result != null)
				return result;
		}

		return doCommand(this, args[0], args);
	}

	private String doCommand(Object target, String method, String[] args) {
		if (target == null)
			; // System.out.println("Huh? Target should never be null " +
		// domain);
		else {
			String cname = "_" + method.replaceAll("-", "_");
			try {
				Method m = target.getClass().getMethod(cname, new Class[] { String[].class });
				return (String) m.invoke(target, new Object[] { args });
			} catch (NoSuchMethodException e) {
				// Ignore
			} catch (InvocationTargetException e) {
				if ( e.getCause() instanceof IllegalArgumentException ) {
					domain.error("%s, for cmd: %s, arguments; %s", e.getMessage(), method, Arrays.toString(args));
				} else {
					domain.warning("Exception in replace: " + e.getCause());
					e.getCause().printStackTrace();
				}
			} catch (Exception e) {
				domain.warning("Exception in replace: " + e + " method=" + method);
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * Return a unique list where the duplicates are removed.
	 * 
	 * @param args
	 * @return
	 */
	static String	_uniqHelp	= "${uniq;<list> ...}";

	public String _uniq(String args[]) {
		verifyCommand(args, _uniqHelp, null, 1, Integer.MAX_VALUE);
		Set<String> set = new LinkedHashSet<String>();
		for (int i = 1; i < args.length; i++) {
			Processor.split(args[i], set);
		}
		return Processor.join(set, ",");
	}

	public String _pathseparator(String args[]) {
		return File.pathSeparator;
	}

	public String _separator(String args[]) {
		return File.separator;
	}

	public String _filter(String args[]) {
		return filter(args, false);
	}

	public String _filterout(String args[]) {
		return filter(args, true);

	}

	static String	_filterHelp	= "${%s;<list>;<regex>}";

	String filter(String[] args, boolean include) {
		verifyCommand(args, String.format(_filterHelp, args[0]), null, 3, 3);

		Collection<String> list = new ArrayList<String>(Processor.split(args[1]));
		Pattern pattern = Pattern.compile(args[2]);

		for (Iterator<String> i = list.iterator(); i.hasNext();) {
			if (pattern.matcher(i.next()).matches() == include)
				i.remove();
		}
		return Processor.join(list);
	}

	static String	_sortHelp	= "${sort;<list>...}";

	public String _sort(String args[]) {
		verifyCommand(args, _sortHelp, null, 2, Integer.MAX_VALUE);

		List<String> result = new ArrayList<String>();
		for (int i = 1; i < args.length; i++) {
			Processor.split(args[i], result);
		}
		Collections.sort(result);
		return Processor.join(result);
	}

	static String	_joinHelp	= "${join;<list>...}";

	public String _join(String args[]) {

		verifyCommand(args, _joinHelp, null, 1, Integer.MAX_VALUE);

		List<String> result = new ArrayList<String>();
		for (int i = 1; i < args.length; i++) {
			Processor.split(args[i], result);
		}
		return Processor.join(result);
	}

	static String	_ifHelp	= "${if;<condition>;<iftrue> [;<iffalse>] }";

	public String _if(String args[]) {
		verifyCommand(args, _ifHelp, null, 3, 4);
		String condition = args[1].trim();
		if (condition.length() != 0)
			return args[2];
		if (args.length > 3)
			return args[3];
		else
			return "";
	}

	public String _now(String args[]) {
		return new Date().toString();
	}

	public static String	_fmodifiedHelp	= "${fmodified;<list of filenames>...}, return latest modification date";

	public String _fmodified(String args[]) throws Exception {
		verifyCommand(args, _fmodifiedHelp, null, 2, Integer.MAX_VALUE);

		long time = 0;
		Collection<String> names = new ArrayList<String>();
		for (int i = 1; i < args.length; i++) {
			Processor.split(args[i], names);
		}
		for (String name : names) {
			File f = new File(name);
			if (f.exists() && f.lastModified() > time)
				time = f.lastModified();
		}
		return "" + time;
	}

	public String _long2date(String args[]) {
		try {
			return new Date(Long.parseLong(args[1])).toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "not a valid long";
	}

	public String _literal(String args[]) {
		if (args.length != 2)
			throw new RuntimeException("Need a value for the ${literal;<value>} macro");
		return "${" + args[1] + "}";
	}

	public String _def(String args[]) {
		if (args.length != 2)
			throw new RuntimeException("Need a value for the ${def;<value>} macro");

		return domain.getProperty(args[1], "");
	}

	/**
	 * 
	 * replace ; <list> ; regex ; replace
	 * 
	 * @param args
	 * @return
	 */
	public String _replace(String args[]) {
		if (args.length != 4) {
			domain.warning("Invalid nr of arguments to replace " + Arrays.asList(args));
			return null;
		}

		String list[] = args[1].split("\\s*,\\s*");
		StringBuffer sb = new StringBuffer();
		String del = "";
		for (int i = 0; i < list.length; i++) {
			String element = list[i].trim();
			if (!element.equals("")) {
				sb.append(del);
				sb.append(element.replaceAll(args[2], args[3]));
				del = ", ";
			}
		}

		return sb.toString();
	}

	public String _warning(String args[]) {
		for (int i = 1; i < args.length; i++) {
			domain.warning(process(args[i]));
		}
		return "";
	}

	public String _error(String args[]) {
		for (int i = 1; i < args.length; i++) {
			domain.error(process(args[i]));
		}
		return "";
	}

	/**
	 * toclassname ; <path>.class ( , <path>.class ) *
	 * 
	 * @param args
	 * @return
	 */
	static String	_toclassnameHelp	= "${classname;<list of class names>}, convert class paths to FQN class names ";

	public String _toclassname(String args[]) {
		verifyCommand(args, _toclassnameHelp, null, 2, 2);
		Collection<String> paths = Processor.split(args[1]);

		List<String> names = new ArrayList<String>(paths.size());
		for (String path : paths) {
			if (path.endsWith(".class")) {
				String name = path.substring(0, path.length() - 6).replace('/', '.');
				names.add(name);
			} else if (path.endsWith(".java")) {
				String name = path.substring(0, path.length() - 5).replace('/', '.');
				names.add(name);
			} else {
				domain.warning("in toclassname, " + args[1]
						+ " is not a class path because it does not end in .class");
			}
		}
		return Processor.join(names, ",");
	}

	/**
	 * toclassname ; <path>.class ( , <path>.class ) *
	 * 
	 * @param args
	 * @return
	 */

	static String	_toclasspathHelp	= "${toclasspath;<list>[;boolean]}, convert a list of class names to paths";

	public String _toclasspath(String args[]) {
		verifyCommand(args, _toclasspathHelp, null, 2, 3);
		boolean cl = true;
		if (args.length > 2)
			cl = new Boolean(args[2]);

		Collection<String> names = Processor.split(args[1]);
		Collection<String> paths = new ArrayList<String>(names.size());
		for (String name : names) {
			String path = name.replace('.', '/') + (cl ? ".class" : "");
			paths.add(path);
		}
		return Processor.join(paths, ",");
	}

	public String _dir(String args[]) {
		if (args.length < 2) {
			domain.warning("Need at least one file name for ${dir;...}");
			return null;
		} else {
			String del = "";
			StringBuffer sb = new StringBuffer();
			for (int i = 1; i < args.length; i++) {
				File f = domain.getFile(args[i]);
				if (f.exists() && f.getParentFile().exists()) {
					sb.append(del);
					sb.append(f.getParentFile().getAbsolutePath());
					del = ",";
				}
			}
			return sb.toString();
		}

	}

	public String _basename(String args[]) {
		if (args.length < 2) {
			domain.warning("Need at least one file name for ${basename;...}");
			return null;
		} else {
			String del = "";
			StringBuffer sb = new StringBuffer();
			for (int i = 1; i < args.length; i++) {
				File f = domain.getFile(args[i]);
				if (f.exists() && f.getParentFile().exists()) {
					sb.append(del);
					sb.append(f.getName());
					del = ",";
				}
			}
			return sb.toString();
		}

	}

	public String _isfile(String args[]) {
		if (args.length < 2) {
			domain.warning("Need at least one file name for ${isfile;...}");
			return null;
		} else {
			boolean isfile = true;
			for (int i = 1; i < args.length; i++) {
				File f = new File(args[i]).getAbsoluteFile();
				isfile &= f.isFile();
			}
			return isfile ? "true" : "false";
		}

	}

	public String _isdir(String args[]) {
		if (args.length < 2) {
			domain.warning("Need at least one file name for ${isdir;...}");
			return null;
		} else {
			boolean isdir = true;
			for (int i = 1; i < args.length; i++) {
				File f = new File(args[i]).getAbsoluteFile();
				isdir &= f.isDirectory();
			}
			return isdir ? "true" : "false";
		}

	}

	public String _tstamp(String args[]) {
		String format = "yyyyMMddHHmm";
		long now = System.currentTimeMillis();

		if (args.length > 1) {
			format = args[1];
			if (args.length > 2) {
				now = Long.parseLong(args[2]);
				if (args.length > 3) {
					domain.warning("Too many arguments for tstamp: " + Arrays.toString(args));
				}
			}
		}
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(new Date(now));
	}

	/**
	 * Wildcard a directory. The lists can contain Instruction that are matched
	 * against the given directory
	 * 
	 * ${lsr;<dir>;<list>(;<list>)*} ${lsa;<dir>;<list>(;<list>)*}
	 * 
	 * @author aqute
	 * 
	 */

	public String _lsr(String args[]) {
		return ls(args, true);
	}

	public String _lsa(String args[]) {
		return ls(args, false);
	}

	String ls(String args[], boolean relative) {
		if (args.length < 2)
			throw new IllegalArgumentException(
					"the ${ls} macro must at least have a directory as parameter");

		File dir = domain.getFile(args[1]);
		if (!dir.isAbsolute())
			throw new IllegalArgumentException(
					"the ${ls} macro directory parameter is not absolute: " + dir);

		if (!dir.exists())
			throw new IllegalArgumentException(
					"the ${ls} macro directory parameter does not exist: " + dir);

		if (!dir.isDirectory())
			throw new IllegalArgumentException(
					"the ${ls} macro directory parameter points to a file instead of a directory: "
							+ dir);

		String[] files = dir.list();
		List<String> result;

		if (args.length < 3) {
			result = Arrays.asList(files);
		} else
			result = new ArrayList<String>();

		for (int i = 2; i < args.length; i++) {
			String parts[] = args[i].split("\\s*,\\s*");
			for (String pattern : parts) {
				// So make it in to an instruction
				Instruction instr = Instruction.getPattern(pattern);

				// For each project, match it against the instruction
				for (int f = 0; f < files.length; f++) {
					if (files[f] != null) {
						if (instr.matches(files[f])) {
							if (!instr.isNegated()) {
								if (relative)
									result.add(files[f]);
								else
									result.add(new File(dir, files[f]).getAbsolutePath());
							}
							files[f] = null;
						}
					}
				}
			}
		}
		return Processor.join(result, ",");
	}

	public String _currenttime(String args[]) {
		return Long.toString(System.currentTimeMillis());
	}

	/**
	 * Modify a version to set a version policy. Thed policy is a mask that is
	 * mapped to a version.
	 * 
	 * <pre>
	 * +           increment
	 * -           decrement
	 * =           maintain
	 * &tilde;           discard
	 * 
	 * ==+      = maintain major, minor, increment micro, discard qualifier
	 * &tilde;&tilde;&tilde;=     = just get the qualifier
	 * version=&quot;[${version;==;${@}},${version;=+;${@}})&quot;
	 * </pre>
	 * 
	 * 
	 * 
	 * 
	 * @param args
	 * @return
	 */
	final static String		MASK_STRING			= "[\\-+=~0123456789]{0,3}[=~]?";
	final static Pattern	MASK				= Pattern.compile(MASK_STRING);
	final static String		_versionHelp		= "${version;<mask>;<version>}, modify a version\n"
														+ "<mask> ::= [ M [ M [ M [ MQ ]]]\n"
														+ "M ::= '+' | '-' | MQ\n"
														+ "MQ ::= '~' | '='";
	final static Pattern	_versionPattern[]	= new Pattern[] { null, null, MASK,
			Verifier.VERSION					};

	public String _version(String args[]) {
		verifyCommand(args, _versionHelp, null, 2, 3);

		String mask = args[1];

		Version version = null;
		if (args.length >= 3)
			version = new Version(args[2]);

		return version(version, mask);
	}

	String version(Version version, String mask) {
		if (version == null) {
			String v = domain.getProperty("@");
			if (v == null) {
				domain
						.error(
								"No version specified for ${version} or ${range} and no implicit version ${@} either, mask=%s",
								mask);
				v = "0";
			}
			version = new Version(v);
		}

		StringBuilder sb = new StringBuilder();
		String del = "";

		for (int i = 0; i < mask.length(); i++) {
			char c = mask.charAt(i);
			String result = null;
			if (c != '~') {
				if (i == 3) {
					result = version.getQualifier();
				} else if (Character.isDigit(c)) {
					// Handle masks like +00, =+0
					result = String.valueOf(c);
				} else {
					int x = version.get(i);
					switch (c) {
					case '+':
						x++;
						break;
					case '-':
						x--;
						break;
					case '=':
						break;
					}
					result = Integer.toString(x);
				}
				if (result != null) {
					sb.append(del);
					del = ".";
					sb.append(result);
				}
			}
		}
		return sb.toString();
	}

	/**
	 * Schortcut for version policy
	 * 
	 * <pre>
	 * -provide-policy : ${policy;[==,=+)}
	 * -consume-policy : ${policy;[==,+)}
	 * </pre>
	 * 
	 * @param args
	 * @return
	 */

	static Pattern	RANGE_MASK		= Pattern.compile("(\\[|\\()(" + MASK_STRING + "),(" + MASK_STRING +")(\\]|\\))");
	static String	_rangeHelp		= "${range;<mask>[;<version>]}, range for version, if version not specified lookyp ${@}\n"
											+ "<mask> ::= [ M [ M [ M [ MQ ]]]\n"
											+ "M ::= '+' | '-' | MQ\n" + "MQ ::= '~' | '='";
	static Pattern	_rangePattern[]	= new Pattern[] { null, RANGE_MASK };

	public String _range(String args[]) {
		verifyCommand(args, _rangeHelp, _rangePattern, 2, 3);
		Version version = null;
		if (args.length >= 3)
			version = new Version(args[2]);

		String spec = args[1];

		Matcher m = RANGE_MASK.matcher(spec);
		m.matches();
		String floor = m.group(1);
		String floorMask = m.group(2);
		String ceilingMask = m.group(3);
		String ceiling = m.group(4);

		StringBuilder sb = new StringBuilder();
		sb.append(floor);
		sb.append(version(version, floorMask));
		sb.append(",");
		sb.append(version(version, ceilingMask));
		sb.append(ceiling);

		String s = sb.toString();
		VersionRange vr = new VersionRange(s);
		if (!(vr.includes(vr.getHigh()) || vr.includes(vr.getLow()))) {
			domain.error("${range} macro created an invalid range %s from %s and mask %s", s,
					version, spec);
		}
		return sb.toString();
	}

	/**
	 * System command. Execute a command and insert the result.
	 * 
	 * @param args
	 * @param help
	 * @param patterns
	 * @param low
	 * @param high
	 */
	public String _system(String args[]) throws Exception {
		verifyCommand(args, "${system;<command>[;<in>]}, execute a system command", null, 2, 3);
		String command = args[1];
		String input = null;

		if (args.length > 2) {
			input = args[2];
		}

		Process process = Runtime.getRuntime().exec(command, null, domain.getBase());
		if (input != null) {
			process.getOutputStream().write(input.getBytes("UTF-8"));
		}
		process.getOutputStream().close();

		String s = IO.collect(process.getInputStream(), "UTF-8");
		int exitValue = process.waitFor();
		if (exitValue != 0) {
			domain.error("System command " + command + " failed with " + exitValue);
		}
		return s.trim();
	}

	public String _env(String args[]) {
		verifyCommand(args, "${env;<name>}, get the environmet variable", null, 2, 2);

		try {
			return System.getenv(args[1]);
		} catch (Throwable t) {
			return null;
		}
	}

	/**
	 * Get the contents of a file.
	 * 
	 * @param in
	 * @return
	 * @throws IOException
	 */

	public String _cat(String args[]) throws IOException {
		verifyCommand(args, "${cat;<in>}, get the content of a file", null, 2, 2);
		File f = domain.getFile(args[1]);
		if (f.isFile()) {
			return IO.collect(f);
		} else if (f.isDirectory()) {
			return Arrays.toString(f.list());
		} else {
			try {
				URL url = new URL(args[1]);
				return IO.collect(url, "UTF-8");
			} catch (MalformedURLException mfue) {
				// Ignore here
			}
			return null;
		}
	}

	public static void verifyCommand(String args[], String help, Pattern[] patterns, int low,
			int high) {
		String message = "";
		if (args.length > high) {
			message = "too many arguments";
		} else if (args.length < low) {
			message = "too few arguments";
		} else {
			for (int i = 0; patterns != null && i < patterns.length && i < args.length; i++) {
				if (patterns[i] != null) {
					Matcher m = patterns[i].matcher(args[i]);
					if (!m.matches())
						message += String.format("Argument %s (%s) does not match %s\n", i,
								args[i], patterns[i].pattern());
				}
			}
		}
		if (message.length() != 0) {
			StringBuilder sb = new StringBuilder();
			String del = "${";
			for (String arg : args) {
				sb.append(del);
				sb.append(arg);
				del = ";";
			}
			sb.append("}, is not understood. ");
			sb.append(message);
			throw new IllegalArgumentException(sb.toString());
		}
	}

	// Helper class to track expansion of variables
	// on the stack.
	static class Link {
		Link	previous;
		String	key;
		Processor start;

		public Link(Processor start, Link previous, String key) {
			this.previous = previous;
			this.key = key;
			this.start = start;
		}

		public boolean contains(String key) {
			if (this.key.equals(key))
				return true;

			if (previous == null)
				return false;

			return previous.contains(key);
		}

		public String toString() {
			StringBuffer sb = new StringBuffer();
			String del = "[";
			for (Link r = this; r != null; r = r.previous) {
				sb.append(del);
				sb.append(r.key);
				del = ",";
			}
			sb.append("]");
			return sb.toString();
		}
	}

	/**
	 * Take all the properties and translate them to actual values. This method
	 * takes the set properties and traverse them over all entries, including
	 * the default properties for that properties. The values no longer contain
	 * macros.
	 * 
	 * @return A new Properties with the flattened values
	 */
	public Properties getFlattenedProperties() {
		// Some macros only work in a lower processor, so we
		// do not report unknown macros while flattening
		flattening = true;
		try {
			Properties flattened = new Properties();
			Properties source = domain.getProperties();
			for (Enumeration<?> e = source.propertyNames(); e.hasMoreElements();) {
				String key = (String) e.nextElement();
				if (!key.startsWith("_"))
					if (key.startsWith("-"))
						flattened.put(key, source.getProperty(key));
					else
						flattened.put(key, process(source.getProperty(key)));
			}
			return flattened;
		} finally {
			flattening = false;
		}
	};

	public static String	_fileHelp	= "${file;<base>;<paths>...}, create correct OS dependent path";

	public String _osfile(String args[]) {
		verifyCommand(args, _fileHelp, null, 3, 3);
		File base = new File(args[1]);
		File f = Processor.getFile(base, args[2]);
		return f.getAbsolutePath();
	}

	public String _path(String args[]) {
		List<String> list = new ArrayList<String>();
		for (int i = 1; i < args.length; i++) {
			list.addAll(Processor.split(args[i]));
		}
		return Processor.join(list, File.pathSeparator);
	}

	public static Properties getParent(Properties p) {
		try {
			Field f = Properties.class.getDeclaredField("defaults");
			f.setAccessible(true);
			return (Properties) f.get(p);
		} catch (Exception e) {
			Field[] fields = Properties.class.getFields();
			System.out.println(Arrays.toString(fields));
			return null;
		}
	}

	public String process(String line) {
		return process(line,domain);
	}

}
