content: /**
   *  Copyright (c) 2015-2016 Angelo ZERR.
   *  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:
   *  Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
   */
  package ts.cmd.tslint;
  
  import java.util.Scanner;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  import com.eclipsesource.json.Json;
  import com.eclipsesource.json.JsonArray;
  import com.eclipsesource.json.JsonObject;
  import com.eclipsesource.json.JsonValue;
  
  import ts.client.Location;
  import ts.cmd.ITypeScriptLinterHandler;
  import ts.cmd.Severity;
  import ts.utils.StringUtils;
  
  /**
   * TypeScript Compiler (tsc) helper.
   *
   */
  public class TslintHelper {
  
  	// ex: "(no-var-keyword) sample.ts[1, 1]: forbidden 'var' keyword, use 'let'
  	// or 'const' instead", errors);
  	// sample.ts(1,14): error TS1003: Identifier expected.
  
  	private static final Pattern TSLINT_PATTERN = Pattern
  			.compile("^\\(\\s*(.*)\\)\\s([^\\s].*)\\[(\\d+,\\s*\\d+)\\]:\\s*(.*)$");
  
  	/**
  	 * Process "tslint" message and call the well
  	 * {@link ITypeScriptLinterHandler} method.
  	 * 
  	 * @param text
  	 * @param handler
  	 */
  	public static void processVerboseMessage(String text, ITypeScriptLinterHandler handler) {
  		if (StringUtils.isEmpty(text)) {
  			return;
  		}
  
  		Scanner scanner = null;
  		try {
  			scanner = new Scanner(text);
  			while (scanner.hasNextLine()) {
  				String line = scanner.nextLine();
  				line = line.trim(); // remove leading whitespace
  				Matcher m = TSLINT_PATTERN.matcher(line);
  				if (m.matches()) {
  					// Error in an ts file.
  					String code = m.group(1);
  					String file = m.group(2);
  					String[] location = m.group(3).split(",");
  					Location startLoc = createLocation(location, true);
  					Location endLoc = null; // createLocation(location, false);
  					String message = m.group(4);
  					handler.addError(file, startLoc, endLoc, Severity.error, code, message);
  				}
  			}
  		} finally {
  			if (scanner != null) {
  				scanner.close();
  			}
  		}
  	}
  
  	private static Location createLocation(String[] location, boolean start) {
  		if (start) {
  			int line = getInt(location, 0);
  			int offset = getInt(location, 1);
  			return new Location(line, offset);
  		}
  		return null;
  	}
  
  	private static int getInt(String[] location, int index) {
  		if (index < location.length) {
  			return Integer.parseInt(location[index].trim());
  		}
  		return 0;
  	}
  
  	public static void processJsonMessage(String text, ITypeScriptLinterHandler handler) {
  		if (StringUtils.isEmpty(text)) {
  			return;
  		}
  
  		Scanner scanner = null;
  		try {
  			scanner = new Scanner(text);
  			while (scanner.hasNextLine()) {
  				String line = scanner.nextLine();
  				line = line.trim(); // remove leading whitespace
  				JsonArray array = Json.parse(line).asArray();
  				for (JsonValue value : array) {
  					// [{"endPosition":{"character":3,"line":0,"position":3},"failure":"forbidden
  					// 'var' keyword, use 'let' or 'const'
  					// instead","name":"sample.ts","ruleName":"no-var-keyword","startPosition":{"character":0,"line":0,"position":0}},{"endPosition":{"character":13,"line":0,"position":13},"failure":"missing
  					// semicolon","name":"sample.ts","ruleName":"semicolon","startPosition":{"character":13,"line":0,"position":13}},{"endPosition":{"character":12,"line":0,"position":12},"failure":"missing
  					// whitespace","name":"sample.ts","ruleName":"whitespace","startPosition":{"character":11,"line":0,"position":11}}]
  					JsonObject item = value.asObject();
  					String name = item.getString("name", null);
  					String ruleName = item.getString("ruleName", null);
  					String failure = item.getString("failure", null);
  					Location startLoc = createLocation(item.get("startPosition"));
  					Location endLoc = createLocation(item.get("endPosition"));
  					handler.addError(name, startLoc, endLoc, Severity.error, ruleName, failure);
  				}
  			}
  		} finally {
  			if (scanner != null) {
  				scanner.close();
  			}
  		}
  	}
  
  	private static Location createLocation(JsonValue value) {
  		if (value == null || !value.isObject()) {
  			return null;
  		}
  		JsonObject loc = value.asObject();
  		return new Location(loc.getInt("line", -1), loc.getInt("character", -1), loc.getInt("position", -1));
  	}
  
  }