/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.releng.tools;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSTag;
import org.eclipse.team.internal.ccvs.core.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;

/**
 * This class provides access to information stored in RelEng map files
 */
public class MapEntry {
	
	private static final String HEAD = "HEAD";
	private static final String KEY_TAG = "tag"; //$NON-NLS-1$
	private static final String KEY_PATH = "path"; //$NON-NLS-1$
	private static final String KEY_CVSROOT = "cvsRoot"; //$NON-NLS-1$
	private static final String KEY_PASSWORD = "password"; //$NON-NLS-1$
	private static final String EMPTY_STRING = ""; //$NON-NLS-1$

	private boolean valid = false;
	private String type = EMPTY_STRING;
	private String id = EMPTY_STRING;
	private OrderedMap<String, String> arguments = new OrderedMap<String, String>();
	private boolean legacy = false;
	private String version;

	public static void main (String[] args)  {
		// For testing only
		
		String[] strings = {
			"",
			" ",
			"type",
			"type@",
			"type@id",
			"type@id=",
			"type@id=tag,",
			"type@id=tag, connectString",
			"type@id=tag, connectString,",
			"type@id=tag, connectString,password",
			"type@id=tag, connectString,password,",
			"type@id=tag, connectString,password,moduleName",
			"type@id=tag, connectString,,moduleName",
			"!***************  FEATURE CONTRIBUTION  ******************************************************",
			"@",
			"=",
			",,,",
			"@=,,,,",
			"type@id,version=CVS,tag=myTag,cvsRoot=myCvsRoot,password=password,path=myPath",
		};
		
		for (int i = 0; i < strings.length; i++) {
			String string = strings[i];
			MapEntry anEntry = new MapEntry(string);

			System.out.println("-----------------------------------------------");
			System.out.println("input: " + string);
			System.out.println("map string: " + anEntry.getMapString());
//			System.out.println(anEntry.getReferenceString());
			anEntry.display();
		}
		
	}
	
	/**
	 * 
	 */
	private void display() {
		// For testing only
		System.out.println("Is Valid: " + isValid());
		System.out.println("Type: " + getType());
		System.out.println("Project Name: " + getId());
		System.out.println("Tag: " + getTagName());
		if (version != null)
			System.out.println("Version: " + version);
		System.out.println("Connect: " + getRepo());
		System.out.println("Password: " + getPassword());
		System.out.println("CVS Module: " + getCVSModule());
	}
	
	public MapEntry(String entryLine) {
		init(entryLine);
	}

	/**
	 * Parse a map file entry line
	 * @param entryLine
	 */	
	private void init(String entryLine) {
		valid = false;
	
		// check for commented out entry
		if (entryLine.startsWith("#") || entryLine.startsWith("!"))
			return;

		// Type	
		int start = 0;
		int end = entryLine.indexOf('@');
		if (end == -1)  return;
		type = entryLine.substring(start, end).trim();
		
		// Project Name
		start = end + 1;
		end = entryLine.indexOf('=', start);
		if (end == -1) return;
		id = entryLine.substring(start, end).trim();
		// we have a version that we have to strip off
		int comma = id.indexOf(',');
		if (comma != -1) {
			version = id.substring(comma + 1);
			id = id.substring(0, comma);
		}

		String[] args = getArrayFromStringWithBlank(entryLine.substring(end + 1), ",");
		this.arguments = populate(args);
		String tag = arguments.get(KEY_TAG);
		String repo = arguments.get(KEY_CVSROOT);
		if (tag == null || tag.length() == 0 || repo == null || repo.length() == 0)
			return;
		valid = true;
	}

	/*
	 * Build a table from the given array. In the new format,the array contains
	 * key=value elements. Otherwise we fill in the key based on the old format.
	 */
	private OrderedMap<String, String> populate(String[] entries) {
		OrderedMap<String, String> result = new OrderedMap<String, String>();
		for (int i=0; i<entries.length; i++) {
			String entry = entries[i];
			int index = entry.indexOf('=');
			if (index == -1) {
				// we only handle CVS entries
				if (i == 0 && "CVS".equalsIgnoreCase(entry)) 
					continue;
				// legacy story...
				return legacyPopulate(entries);
			}
			String key = entry.substring(0, index);
			String value = entry.substring(index + 1);
			result.put(key, value);
		}
		result.toString();
		return result;
	}
	
	private OrderedMap<String, String> legacyPopulate(String[] entries) {
		legacy = true;
		OrderedMap<String, String> result = new OrderedMap<String, String>();
		// must have at least tag and connect string
		if (entries.length >= 2) {
			// Version
			result.put(KEY_TAG, entries[0]);
			// Repo Connect String
			result.put(KEY_CVSROOT, entries[1]);
			
			// Optional Password.
			if (entries.length >= 3)
				result.put(KEY_PASSWORD, entries[2]);
			
			// Optional CVS Module Name
			if (entries.length >= 4)
				result.put(KEY_PATH, entries[3]);
		}
		return result;
	}

	/**
	 * Convert a list of tokens into an array. The list separator has to be
	 * specified. The specificity of this method is that it returns an empty
	 * element when to same separators are following each others. For example
	 * the string a,,b returns the following array [a, ,b]
	 *  
	 */
	public static String[] getArrayFromStringWithBlank(String list, String separator) {
		if (list == null || list.trim().length() == 0)
			return new String[0];
		List<String> result = new ArrayList<String>();
		boolean previousWasSeparator = true;
		for (StringTokenizer tokens = new StringTokenizer(list, separator, true); tokens.hasMoreTokens();) {
			String token = tokens.nextToken().trim();
			if (token.equals(separator)) {
				if (previousWasSeparator)
					result.add(""); //$NON-NLS-1$
				previousWasSeparator = true;
			} else {
				result.add(token);
				previousWasSeparator = false;
			}
		}
		return result.toArray(new String[result.size()]);
	}

	public String getTagName() {
		String value = arguments.get(KEY_TAG);
		return value == null  || HEAD.equals(value) ? EMPTY_STRING : value;
	}
	
	public CVSTag getTag() {
		if (getTagName().equals(HEAD) || getTagName().equals("")) return CVSTag.DEFAULT; //$NON-NLS-1$
		return new CVSTag(getTagName(), CVSTag.VERSION);
	}
	
	public String getPassword() {
		String value = arguments.get(KEY_PASSWORD);
		return value == null ? EMPTY_STRING : value;
	}

	public String getId() {
		return id;
	}

	private String internalGetCVSModule()  {
		String module = arguments.get(KEY_PATH);
		return module == null ? id : module;
	}
	
	public String getCVSModule() {
		String value = arguments.get(KEY_PATH);
		return value == null ? EMPTY_STRING : value;
	}

	public String getRepo() {
		String value = arguments.get(KEY_CVSROOT);
		return value == null ? EMPTY_STRING : value;
	}

	public String getType() {
		return type;
	}

	public boolean isValid() {
		return valid;
	}
	
	public String getReferenceString()  {
		if (!isValid()) return null;
		// This is the format used by the CVS IProjectSerializer
		String projectName = new Path(internalGetCVSModule()).lastSegment();
		return "1.0," + getRepo() + "," + internalGetCVSModule() + "," + projectName + "," + getTagName();
	}

	public String getMapString() {
		StringBuffer result = new StringBuffer();
		if (legacy) {
			result.append(getType());
			result.append('@');
			result.append(getId());
			if (version != null) {
				result.append(',');
				result.append(version);
			}
			result.append('=');
			result.append(getTagName());
			result.append(',');
			result.append(getRepo());
			result.append(',');
			result.append(getPassword());
			if (!getCVSModule().equals("") || !getPassword().equals(""))
				result.append(',');
			result.append(getCVSModule());
			return result.toString();
		}
		result.append(getType());
		result.append('@');
		result.append(getId());
		if (version != null) {
			result.append(',');
			result.append(version);
		}
		result.append('=');
		result.append("CVS");
		for (Iterator<String> iter = arguments.keys().iterator(); iter.hasNext(); ) {
			String key = iter.next();
			String value = arguments.get(key);
			if (value != null && value.length() > 0)
				result.append(',' + key + '=' + value);
		}
		return result.toString();
	}

	/*
	 * Return the version specified for this entry. Can be null.
	 */
	public String getVersion() {
		return version;
	}
	
	public void setPassword(String password) {
		arguments.put(KEY_PASSWORD, password);
	}

	public void setId(String projectID) {
		this.id = projectID;
	}

	public void setCVSModule(String path) {
		arguments.put(KEY_PATH, path);
	}

	public void setRepo(String repo) {
		arguments.put(KEY_CVSROOT, repo);
	}

	public void setTagName(String tagName) {
		arguments.put(KEY_TAG, tagName);
	}

	public void setType(String type) {
		this.type = type;
	}

	public void setValid(boolean valid) {
		this.valid = valid;
	}
	
	@Override
	public String toString() {
		return "Entry: " + getMapString();
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof MapEntry) {
			return ((MapEntry)obj).getMapString().equals(getMapString());
		}
		return super.equals(obj);
	}
	
	/**
	 * Return true if this map entry is mapped to the given CVS module
	 * @param moduleName
	 */
	public boolean isMappedTo(String moduleName) {
		IPath entryPath = new Path(internalGetCVSModule());
		IPath modulePath = new Path(moduleName);
		if (entryPath.segmentCount() != modulePath.segmentCount()) return false;
		for (int i = 0; i < entryPath.segmentCount(); i++) {
			if (!entryPath.segment(i).equals(modulePath.segment(i))) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Return <code>true</code> if the entry is mapped to the given project
	 * and <code>false</code> otherwise.
	 */
	public boolean isMappedTo(IProject project) {
		String moduleName;
		try {
			moduleName = getCVSModule(project);
			if (moduleName == null) return false;
			return isMappedTo(moduleName);
		} catch (CVSException e) {
			RelEngPlugin.getDefault().getLog().log(e.getStatus());
			return false;
		}
	}
	
	/**
	 * Get the remote CVS module for the project or <code>null</code>
	 * if the project is not a CVS project.
	 */
	private String getCVSModule(IProject project) throws CVSException {
		ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor(project);
		FolderSyncInfo info = folder.getFolderSyncInfo();
		if (info == null) {
			return null;
		}
		return info.getRepository();
	}

}
