/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 *******************************************************************************/
package org.eclipse.dltk.compiler.problem;

import java.util.Arrays;

import org.eclipse.dltk.compiler.util.Messages;
import org.eclipse.dltk.compiler.util.Util;
import org.eclipse.dltk.core.DLTKCore;

public class DefaultProblem extends CategorizedProblem {

	private static int hashCode(Object[] array) {
		final int prime = 31;
		if (array == null)
			return 0;
		int result = 1;
		for (int index = 0; index < array.length; index++) {
			result = prime * result
					+ (array[index] == null ? 0 : array[index].hashCode());
		}
		return result;
	}

	private String fileName;

	private IProblemIdentifier id;

	private int startPosition, endPosition, line, column;

	private ProblemSeverity severity;

	private String[] arguments;

	private String message;

	public static final String MARKER_TYPE_PREFIX = "org.eclipse.dltk"; //$NON-NLS-1$

	public static final String MARKER_TYPE_PROBLEM = "org.eclipse.dltk.core.problem"; //$NON-NLS-1$

	public static final String MARKER_TYPE_TASK = "org.eclipse.dltk.core.task"; //$NON-NLS-1$

	public static final Object[] EMPTY_VALUES = {};

	public DefaultProblem(String originatingFileName, String message,
			IProblemIdentifier id, String[] stringArguments,
			ProblemSeverity severity, int startPosition, int endPosition,
			int line, int column) {
		this.fileName = originatingFileName;
		this.message = message;
		this.id = id;
		this.arguments = stringArguments;
		this.severity = severity;
		this.startPosition = startPosition;
		this.endPosition = endPosition;
		this.line = line;
		this.column = column;
	}

	@Deprecated
	public DefaultProblem(String originatingFileName, String message, int id,
			String[] stringArguments, ProblemSeverity severity,
			int startPosition, int endPosition, int line) {
		this(originatingFileName, message, DefaultProblemIdentifier.decode(id),
				stringArguments, severity, startPosition, endPosition, line, 0);
	}

	@Deprecated
	public DefaultProblem(String message, int id, String[] stringArguments,
			ProblemSeverity severity, int startPosition, int endPosition,
			int line) {
		this(NONAME, message, DefaultProblemIdentifier.decode(id),
				stringArguments, severity, startPosition, endPosition, line, 0);
	}

	public DefaultProblem(String message, IProblemIdentifier id,
			String[] stringArguments, ProblemSeverity severity,
			int startPosition, int endPosition, int line) {
		this(NONAME, message, id, stringArguments, severity, startPosition,
				endPosition, line, 0);
	}

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

	public String errorReportSource(char[] unitSource) {
		return errorReportSource(unitSource, 0);
	}

	public String errorReportSource(char[] unitSource, int tagBits) {
		// extra from the source the inaccurate token
		// and "highlight" it using some underneath ^^^^^
		// put some context around too.

		// this code assumes that the font used in the console is fixed size

		// sanity .....
		if ((this.startPosition > this.endPosition)
				|| ((this.startPosition < 0) && (this.endPosition < 0))
				|| unitSource.length == 0)
			return Messages.problem_noSourceInformation;

		StringBuffer errorBuffer = new StringBuffer();
		if (DLTKCore.DEBUG) {
			System.err.println("TODO: Add correct code here. DefaultProblem"); //$NON-NLS-1$
		}
		// if ((tagBits & Main.Logger.EMACS) == 0) {
		// errorBuffer.append(' ').append(Messages.bind(Messages.problem_atLine,
		// String.valueOf(this.line)));
		// errorBuffer.append(Util.LINE_SEPARATOR);
		// }
		errorBuffer.append('\t');

		char c;
		final char SPACE = '\u0020';
		final char MARK = '^';
		final char TAB = '\t';
		// the next code tries to underline the token.....
		// it assumes (for a good display) that token source does not
		// contain any \r \n. This is false on statements !
		// (the code still works but the display is not optimal !)

		// expand to line limits
		int length = unitSource.length, begin, end;
		for (begin = this.startPosition >= length ? length - 1
				: this.startPosition; begin > 0; begin--) {
			if ((c = unitSource[begin - 1]) == '\n' || c == '\r')
				break;
		}
		for (end = this.endPosition >= length ? length - 1 : this.endPosition; end + 1 < length; end++) {
			if ((c = unitSource[end + 1]) == '\r' || c == '\n')
				break;
		}

		// trim left and right spaces/tabs
		while ((c = unitSource[begin]) == ' ' || c == '\t')
			begin++;
		while ((c = unitSource[end]) == ' ' || c == '\t')
			end--;

		// copy source
		errorBuffer.append(unitSource, begin, end - begin + 1);
		errorBuffer.append(Util.LINE_SEPARATOR).append("\t"); //$NON-NLS-1$

		// compute underline
		for (int i = begin; i < this.startPosition; i++) {
			errorBuffer.append((unitSource[i] == TAB) ? TAB : SPACE);
		}
		for (int i = this.startPosition; i <= (this.endPosition >= length ? length - 1
				: this.endPosition); i++) {
			errorBuffer.append(MARK);
		}
		return errorBuffer.toString();
	}

	/**
	 * Answer back the original arguments recorded into the problem.
	 * 
	 * @return java.lang.String[]
	 */
	@Override
	public String[] getArguments() {
		return this.arguments;
	}

	/**
	 * @see org.eclipse.dltk.core.compiler.CategorizedProblem#getCategoryID()
	 */
	@Override
	public int getCategoryID() {
		// return ProblemReporter.getProblemCategory(this.severity, this.id);
		if (DLTKCore.DEBUG) {
			System.err
					.println("TODO: DefaultProblem getCategoryID always return 0. Fix it."); //$NON-NLS-1$
		}
		return 0;
	}

	/**
	 * Answer the type of problem.
	 * 
	 * @see org.eclipse.dltk.core.compiler.IProblem#getID()
	 * @return int
	 */
	@Override
	public IProblemIdentifier getID() {
		return this.id;
	}

	/**
	 * Answers a readable name for the category which this problem belongs to,
	 * or null if none could be found. FOR TESTING PURPOSE
	 * 
	 * @return java.lang.String
	 */
	public String getInternalCategoryMessage() {
		switch (getCategoryID()) {
		case CAT_UNSPECIFIED:
			return "unspecified"; //$NON-NLS-1$
		case CAT_BUILDPATH:
			return "buildpath"; //$NON-NLS-1$
		case CAT_SYNTAX:
			return "syntax"; //$NON-NLS-1$
		case CAT_IMPORT:
			return "import"; //$NON-NLS-1$
		case CAT_TYPE:
			return "type"; //$NON-NLS-1$
		case CAT_MEMBER:
			return "member"; //$NON-NLS-1$
		case CAT_INTERNAL:
			return "internal"; //$NON-NLS-1$		
		case CAT_CODE_STYLE:
			return "code style"; //$NON-NLS-1$
		case CAT_POTENTIAL_PROGRAMMING_PROBLEM:
			return "potential programming problem"; //$NON-NLS-1$
		case CAT_NAME_SHADOWING_CONFLICT:
			return "name shadowing conflict"; //$NON-NLS-1$
		case CAT_DEPRECATION:
			return "deprecation"; //$NON-NLS-1$
		case CAT_UNNECESSARY_CODE:
			return "unnecessary code"; //$NON-NLS-1$
		case CAT_UNCHECKED_RAW:
			return "unchecked/raw"; //$NON-NLS-1$
		case CAT_NLS:
			return "nls"; //$NON-NLS-1$
		case CAT_RESTRICTION:
			return "restriction"; //$NON-NLS-1$
		}
		return null;
	}

	/**
	 * Returns the marker type associated to this problem.
	 * 
	 * @see org.eclipse.dltk.core.compiler.CategorizedProblem#getMarkerType()
	 */
	@Override
	public String getMarkerType() {
		return isTask() ? MARKER_TYPE_TASK : MARKER_TYPE_PROBLEM;
	}

	/**
	 * @since 3.0
	 */
	@Override
	public boolean isTask() {
		return this.id == IProblem.Task;
	}

	/**
	 * Answer a localized, human-readable message string which describes the
	 * problem.
	 * 
	 * @return java.lang.String
	 */
	@Override
	public String getMessage() {
		return this.message;
	}

	public int getColumn() {
		return this.column;
	}

	/**
	 * Answer the file name in which the problem was found.
	 * 
	 * @return String
	 */
	@Override
	public String getOriginatingFileName() {
		return this.fileName;
	}

	/**
	 * Answer the end position of the problem (inclusive), or -1 if unknown.
	 * 
	 * @return int
	 */
	@Override
	public int getSourceEnd() {
		return this.endPosition;
	}

	/**
	 * Answer the line number in source where the problem begins.
	 * 
	 * @return int
	 */
	@Override
	public int getSourceLineNumber() {
		return this.line;
	}

	/**
	 * Answer the start position of the problem (inclusive), or -1 if unknown.
	 * 
	 * @return int
	 */
	@Override
	public int getSourceStart() {
		return this.startPosition;
	}

	@Override
	public ProblemSeverity getSeverity() {
		return severity;
	}

	@Override
	public void setSeverity(ProblemSeverity severity) {
		this.severity = severity;
	}

	/*
	 * Helper method: checks the severity to see if the Error bit is set.
	 * 
	 * @return boolean
	 */
	@Override
	public boolean isError() {
		return this.severity == ProblemSeverity.ERROR;
	}

	/*
	 * Helper method: checks the severity to see if the Error bit is not set.
	 * 
	 * @return boolean
	 */
	@Override
	public boolean isWarning() {
		return this.severity == ProblemSeverity.WARNING;
	}

	public void setOriginatingFileName(String fileName) {
		this.fileName = fileName;
	}

	/**
	 * Set the end position of the problem (inclusive), or -1 if unknown.
	 * 
	 * Used for shifting problem positions.
	 * 
	 * @param sourceEnd
	 *            the new value of the sourceEnd of the receiver
	 */
	@Override
	public void setSourceEnd(int sourceEnd) {
		this.endPosition = sourceEnd;
	}

	/**
	 * Set the line number in source where the problem begins.
	 * 
	 * @param lineNumber
	 *            the new value of the line number of the receiver
	 */
	@Override
	public void setSourceLineNumber(int lineNumber) {

		this.line = lineNumber;
	}

	/**
	 * Set the start position of the problem (inclusive), or -1 if unknown.
	 * 
	 * Used for shifting problem positions.
	 * 
	 * @param sourceStart
	 *            the new value of the source start position of the receiver
	 */
	@Override
	public void setSourceStart(int sourceStart) {
		this.startPosition = sourceStart;
	}

	@Override
	public String toString() {
		final StringBuffer sb = new StringBuffer();
		sb.append("Pb"); //$NON-NLS-1$
		if (this.id != null) {
			sb.append('#');
			sb.append(this.id.name());
		}
		sb.append(' ');
		sb.append(line);
		sb.append('[');
		sb.append(startPosition);
		sb.append(".."); //$NON-NLS-1$
		sb.append(endPosition);
		sb.append(']');
		sb.append(':');
		if (this.message != null) {
			sb.append(this.message);
		} else {
			if (this.arguments != null) {
				for (int i = 0; i < this.arguments.length; i++) {
					sb.append(' ');
					sb.append(this.arguments[i]);
				}
			}
		}
		return sb.toString();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + DefaultProblem.hashCode(arguments);
		result = prime * result + column;
		result = prime * result + endPosition;
		result = prime * result
				+ ((fileName == null) ? 0 : fileName.hashCode());
		result = prime * result + (id == null ? 0 : id.hashCode());
		result = prime * result + line;
		result = prime * result + ((message == null) ? 0 : message.hashCode());
		result = prime * result + severity.hashCode();
		result = prime * result + startPosition;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final DefaultProblem other = (DefaultProblem) obj;
		if (!Arrays.equals(arguments, other.arguments))
			return false;
		if (column != other.column)
			return false;
		if (endPosition != other.endPosition)
			return false;
		if (fileName == null) {
			if (other.fileName != null)
				return false;
		} else if (!fileName.equals(other.fileName))
			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (line != other.line)
			return false;
		if (message == null) {
			if (other.message != null)
				return false;
		} else if (!message.equals(other.message))
			return false;
		if (severity != other.severity)
			return false;
		if (startPosition != other.startPosition)
			return false;
		return true;
	}
}
