/*******************************************************************************
 * Copyright (c) 2007, 2018 Alphonse Van Assche.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Alphonse Van Assche - initial API and implementation
 *******************************************************************************/

package org.eclipse.linuxtools.internal.rpm.ui.editor;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import org.eclipse.linuxtools.internal.rpm.ui.editor.preferences.PreferenceConstants;
import org.eclipse.linuxtools.internal.rpm.ui.editor.scanners.SpecfileScanner;
import org.eclipse.linuxtools.rpm.core.utils.Utils;

/**
 * This class is used to retrieve and manage the RPM macro proposals list.
 *
 */
public class RpmMacroProposalsList {

	private static final String EMPTY_STRING = ""; //$NON-NLS-1$

	private Map<String, String> macroMap = new HashMap<>();

	private String toStringStr;

	/**
	 * Default contructor
	 */
	public RpmMacroProposalsList() {
		buildMacroList();
	}

	/**
	 * Build the macro list.
	 */
	public final void buildMacroList() {
		for (String definedMacro : SpecfileScanner.DEFINED_MACROS) {
			macroMap.put(definedMacro, Messages.RpmMacroProposalsList_0);
			// TODO find way to provide info about buildin macros.
		}
		String macroProposalsPaths = Activator.getDefault().getPreferenceStore()
				.getString(PreferenceConstants.P_MACRO_PROPOSALS_FILESPATH);
		String[] paths = macroProposalsPaths.split(";"); //$NON-NLS-1$
		// paths must be reversed because the last value added
		// into a Map overwrites the first.
		paths = reverseStringArray(paths);
		for (String path : paths) {
			if (!path.equals(EMPTY_STRING)) {
				File pathFile = new File(path);
				if (pathFile.exists()) {
					if (pathFile.isDirectory()) {
						File[] macrosFiles = pathFile.listFiles();
						for (File macrosFile : macrosFiles) {
							addMacroToMap(macrosFile.getAbsolutePath());
						}
					} else {
						addMacroToMap(path);
					}
				}
			}
		}
	}

	/**
	 * Add macro definition to the map
	 *
	 * @param filename macro file definition.
	 */
	private void addMacroToMap(String filename) {
		String line = EMPTY_STRING;
		try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filename)))) {
			line = reader.readLine();
			String key = EMPTY_STRING, value = EMPTY_STRING;
			while (line != null) {
				if (line.startsWith("%")) { //$NON-NLS-1$
					String[] item = line.split("\t+| ", 2); //$NON-NLS-1$
					try {
						// Get values on more than one line
						if (line.trim().endsWith("\\")) { //$NON-NLS-1$
							value = "\n"; //$NON-NLS-1$
							boolean isKeyLine = true;
							while (line.trim().endsWith("\\")) { //$NON-NLS-1$
								if (isKeyLine) {
									isKeyLine = false;
									key = item[0];
									if (item.length > 1) {
										value += item[1].replace("\\", "\n\n"); //$NON-NLS-1$//$NON-NLS-2$
									}
								} else {
									value += line.substring(0, line.length() - 1).trim() + "\n\t"; //$NON-NLS-1$
								}
								line = reader.readLine();
							}
						} else {
							key = item[0];
							value = item[1];
						}
						key = key.trim();
						value = value.trim();
						macroMap.put(key, value);
						toStringStr += key + ": " + value + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
					} catch (Exception e) {
						line = reader.readLine();
						continue;
					}
					value = EMPTY_STRING;
					key = EMPTY_STRING;
				}
				line = reader.readLine();
			}
		} catch (IOException e) {
			SpecfileLog.logError(e);
		}
	}

	/**
	 * Reverse a <code>String</code> array.
	 *
	 * @param stringArrayToReverse the string array to reverse.
	 * @return the reversed <code>String</code> array.
	 */
	private String[] reverseStringArray(String[] stringArrayToReverse) {
		int left = 0;
		int right = stringArrayToReverse.length - 1;
		while (left < right) {
			String tmp = stringArrayToReverse[left];
			stringArrayToReverse[left] = stringArrayToReverse[right];
			stringArrayToReverse[right] = tmp;
			left++;
			right--;
		}
		return stringArrayToReverse;
	}

	/**
	 * Get proposals for a given prefix
	 *
	 * @param prefix The prefix to search.
	 * @return a <code>Map</code> of proposals.
	 */
	public Map<String, String> getProposals(String prefix) {
		Map<String, String> proposalsMap = new HashMap<>(macroMap.size());
		for (Map.Entry<String, String> entry : macroMap.entrySet()) {
			// Get proposals for macro begin with { char too.
			if (entry.getKey().startsWith(prefix.replaceFirst("\\{", EMPTY_STRING))) { //$NON-NLS-1$
				proposalsMap.put(entry.getKey(), entry.getValue());
			}
		}
		// Sort proposals
		return new TreeMap<>(proposalsMap);
	}

	/**
	 * Get the value for a given macro.
	 *
	 * @param key Key to retrieve value.
	 * @return a string representation of the value
	 */
	public String getValue(String key) {
		String value = macroMap.get("%" + key); //$NON-NLS-1$
		// get proposals for macro contain ? too.
		if (value == null) {
			value = macroMap.get(("%" + key).replaceFirst("\\?", EMPTY_STRING)); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return value;
	}

	/**
	 * Find a key in the macroMap
	 *
	 * @param keyToFind The key to find.
	 * @return return the value
	 */
	public boolean findKey(String keyToFind) {
		return macroMap.containsKey(keyToFind);
	}

	/**
	 * Return the ouput of the <code>rpm --eval</code> command for a given macro.
	 *
	 * @param macroName The macro name to eval.
	 * @return the resolved macro content.
	 */
	public static String getMacroEval(String macroName) {
		String eval = EMPTY_STRING;
		try {
			eval = Utils.runCommandToString("rpm", "--eval", macroName); //$NON-NLS-1$//$NON-NLS-2$
		} catch (IOException e) {
			SpecfileLog.logError(e);
		}
		return eval.trim();
	}

	@Override
	public String toString() {
		return toStringStr;
	}

}
