/*******************************************************************************
 * Copyright (c) 2000, 2016 QNX Software Systems and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     QNX Software Systems - Initial API and implementation
 *     Wind River Systems   - Modified for new DSF Reference Implementation
 *     Jens Elmenthaler (Advantest) - Fix empty names for functions in anonymous namespaces (bug 341336)
 *******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.output;

/**
 * GDB/MI Frame tuple parsing.
 */
public class MIFrame {

	int level;
	String addr;
	String func = ""; //$NON-NLS-1$
	String file = ""; //$NON-NLS-1$
	// since gdb 6.4
	String fullname = ""; //$NON-NLS-1$
	int line;
	MIArg[] args = new MIArg[0];

	public MIFrame(MITuple tuple) {
		parse(tuple);
	}

	public MIArg[] getArgs() {
		return args;
	}

	public String getFile() {
		String fname = getFullname();
		return (fname.length() != 0) ? fname : file;
	}

	public String getFullname() {
		return fullname;
	}

	public String getFunction() {
		return func;
	}

	public int getLine() {
		return line;
	}

	public String getAddress() {
		return addr;
	}

	public int getLevel() {
		return level;
	}

	@Override
	public String toString() {
		StringBuilder buffer = new StringBuilder();
		buffer.append("level=\"").append(level).append('"'); //$NON-NLS-1$
		buffer.append(",addr=\"").append(addr).append('"'); //$NON-NLS-1$
		buffer.append(",func=\"").append(func).append('"'); //$NON-NLS-1$
		buffer.append(",file=\"").append(file).append('"'); //$NON-NLS-1$
		buffer.append(",fullname=\"").append(fullname).append('"'); //$NON-NLS-1$
		buffer.append(",line=\"").append(line).append('"'); //$NON-NLS-1$
		buffer.append(",args=["); //$NON-NLS-1$
		for (int i = 0; i < args.length; i++) {
			if (i != 0) {
				buffer.append(',');
			}
			buffer.append("{name=\"").append(args[i].getName()).append('"');//$NON-NLS-1$
			buffer.append(",value=\"").append(args[i].getValue()).append("\"}");//$NON-NLS-1$//$NON-NLS-2$
		}
		buffer.append(']');
		return buffer.toString();
	}

	void parse(MITuple tuple) {
		MIResult[] results = tuple.getMIResults();
		for (int i = 0; i < results.length; i++) {
			String var = results[i].getVariable();
			MIValue value = results[i].getMIValue();
			String str = ""; //$NON-NLS-1$
			if (value != null && value instanceof MIConst) {
				str = ((MIConst) value).getCString();
			}

			if (var.equals("level")) { //$NON-NLS-1$
				try {
					level = Integer.parseInt(str.trim());
				} catch (NumberFormatException e) {
				}
			} else if (var.equals("addr")) { //$NON-NLS-1$
				try {
					addr = str.trim();
					if (str.equals("<unavailable>")) //$NON-NLS-1$
						addr = ""; //$NON-NLS-1$
				} catch (NumberFormatException e) {
				}
			} else if (var.equals("func")) { //$NON-NLS-1$
				func = null;
				if (str != null) {
					str = str.trim();
					if (str.equals("??")) //$NON-NLS-1$
						func = ""; //$NON-NLS-1$
					else {
						func = str;
						// In some situations gdb returns the function names that include parameter types.
						// To make the presentation consistent truncate the parameters. PR 46592
						// However PR180059: only cut it if it is last brackets represent parameters,
						// because gdb can return: func="(anonymous namespace)::func2((anonymous namespace)::Test*)"
						int closing = str.lastIndexOf(')');
						if (closing == str.length() - 1) {
							int end = getMatchingBracketIndex(str, closing - 1);
							if (end >= 0) {
								func = str.substring(0, end);
							}
						}
					}
				}
			} else if (var.equals("file")) { //$NON-NLS-1$
				file = str;
			} else if (var.equals("fullname")) { //$NON-NLS-1$
				fullname = str;
			} else if (var.equals("line")) { //$NON-NLS-1$
				try {
					line = Integer.parseInt(str.trim());
				} catch (NumberFormatException e) {
				}
			} else if (var.equals("args")) { //$NON-NLS-1$
				if (value instanceof MIList) {
					args = MIArg.getMIArgs((MIList) value);
				} else if (value instanceof MITuple) {
					args = MIArg.getMIArgs((MITuple) value);
				}
			}
		}
	}

	private int getMatchingBracketIndex(String str, int end) {
		int depth = 1;
		for (; end >= 0; end--) {
			int c = str.charAt(end);
			if (c == '(') {
				depth--;
				if (depth == 0)
					break;
			} else if (c == ')')
				depth++;
		}
		return end;
	}
}
