/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.metron.parsing.parsers;

import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import com.google.code.regexp.Matcher;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class MetronMatch implements Serializable {

	private static final long serialVersionUID = -1129245286587945311L;
	private String subject; // texte
	  private Map<String, Object> capture;
	  private MetronGarbage garbage;
	  private MetronGrok grok;
	  private Matcher match;
	  private int start;
	  private int end;

	  /**
	   * For thread safety
	   */
	  private static ThreadLocal<MetronMatch> matchHolder = new ThreadLocal<MetronMatch>() {
		  @Override
		  protected MetronMatch initialValue() {
			  return new MetronMatch();
		  }
	  };

	  /**
	   *Create a new {@code Match} object.
	   */
	  public MetronMatch() {
	    subject = "Nothing";
	    grok = null;
	    match = null;
	    capture = new TreeMap<String, Object>();
	    garbage = new MetronGarbage();
	    start = 0;
	    end = 0;
	  }

	  /**
	   * Create Empty grok matcher
	   */
	  public static final MetronMatch EMPTY = new MetronMatch();

	  public void setGrok(MetronGrok grok){
	    if (grok != null) {
	      this.grok = grok;
	    }
	  }

	  public Matcher getMatch() {
	    return match;
	  }

	  public void setMatch(Matcher match) {
	    this.match = match;
	  }

	  public int getStart() {
	    return start;
	  }

	  public void setStart(int start) {
	    this.start = start;
	  }

	  public int getEnd() {
	    return end;
	  }

	  public void setEnd(int end) {
	    this.end = end;
	  }

	  /**
	   * Singleton.
	   *
	   * @return instance of Match
	   */
	  public static MetronMatch getInstance() {
		 return matchHolder.get();
	  }

	  /**
	   *  Set the single line of log to parse.
	   *
	   * @param text : single line of log
	   */
	  public void setSubject(String text) {
	    if (text == null) {
	      return;
	    }
	    if (text.isEmpty()) {
	      return;
	    }
	    subject = text;
	  }

	  /**
	   * Retrurn the single line of log.
	   *
	   * @return the single line of log
	   */
	  public String getSubject() {
	    return subject;
	  }

	  /**
	   * Match to the <tt>subject</tt> the <tt>regex</tt> and save the matched element into a map.
	   *
	   */
	  public void captures() {
	    if (match == null) {
	      return;
	    }
	    capture.clear();

	    // _capture.put("LINE", this.line);
	    // _capture.put("LENGTH", this.line.length() +"");

	    Map<String, String> mappedw = this.match.namedGroups();
	    Iterator<Entry<String, String>> it = mappedw.entrySet().iterator();
	    while (it.hasNext()) {

	      @SuppressWarnings("rawtypes")
	      Map.Entry pairs = (Map.Entry) it.next();
	      String key = null;
	      Object value = null;
	      if (this.grok.getNamedRegexCollectionById(pairs.getKey().toString()) == null) {
	        key = pairs.getKey().toString();
	      } else if (!this.grok.getNamedRegexCollectionById(pairs.getKey().toString()).isEmpty()) {
	        key = this.grok.getNamedRegexCollectionById(pairs.getKey().toString());
	      }
	      if (pairs.getValue() != null) {
	        value = pairs.getValue().toString();
	        
	        KeyValue keyValue = MetronConverter.convert(key, value);
	        
	        //get validated key
	        key = keyValue.getKey();
	        
	        //resolve value
	        if (keyValue.getValue() instanceof String) {
	        	 value = cleanString((String)keyValue.getValue());
	        } else {
	        	value = keyValue.getValue();
	        }
	        
	        //set if grok failure
	        if (keyValue.hasGrokFailure()) {
	        	capture.put(key + "_grokfailure", keyValue.getGrokFailure());
	        }
	      }

	      capture.put(key, value);
	      it.remove(); // avoids a ConcurrentModificationException
	    }
	  }


	  /**
	   * remove from the string the quote and double quote.
	   *
	   * @param string to pure: "my/text"
	   * @return unquoted string: my/text
	   */
	  private String cleanString(String value) {
	    if (value == null) {
	      return value;
	    }
	    if (value.isEmpty()) {
	      return value;
	    }
	    char[] tmp = value.toCharArray();
	    if ((tmp[0] == '"' && tmp[value.length() - 1] == '"')
	        || (tmp[0] == '\'' && tmp[value.length() - 1] == '\'')) {
	      value = value.substring(1, value.length() - 1);
	    }
	    return value;
	  }


	  /**
	   * Get the json representation of the matched element.
	   * <p>
	   * example:
	   * map [ {IP: 127.0.0.1}, {status:200}]
	   * will return
	   * {"IP":"127.0.0.1", "status":200}
	   * </p>
	   * If pretty is set to true, json will return prettyprint json string.
	   *
	   * @return Json of the matched element in the text
	   */
	  public String toJson(Boolean pretty) {
	    if (capture == null) {
	      return "{}";
	    }
	    if (capture.isEmpty()) {
	      return "{}";
	    }

	    this.cleanMap();
	    Gson gs;
	    if (pretty) {
	     gs = new GsonBuilder().setPrettyPrinting().create();
	    } else {
	      gs = new Gson();
	    }
	    return gs.toJson(/* cleanMap( */capture/* ) */);
	  }

	  /**
	   * Get the json representation of the matched element.
	   * <p>
	   * example:
	   * map [ {IP: 127.0.0.1}, {status:200}]
	   * will return
	   * {"IP":"127.0.0.1", "status":200}
	   * </p>
	   *
	   * @return Json of the matched element in the text
	   */
	  public String toJson() {
	    return toJson(false);
	  }

	  /**
	   * Get the map representation of the matched element in the text.
	   *
	   * @return map object from the matched element in the text
	   */
	  public Map<String, Object> toMap() {
	    this.cleanMap();
	    return capture;
	  }

	  /**
	   * Remove and rename the unwanted elelents in the matched map.
	   */
	  private void cleanMap() {
	    garbage.rename(capture);
	    garbage.remove(capture);
	  }

	  /**
	   * Util fct.
	   *
	   * @return boolean
	   */
	  public Boolean isNull() {
	    if (this.match == null) {
	      return true;
	    }
	    return false;
	  }

	  /**
	   * Util fct.
	   *
	   * @param s
	   * @return boolean
	   */
	  private boolean isInteger(String s) {
	    try {
	      Integer.parseInt(s);
	    } catch (NumberFormatException e) {
	      return false;
	    }
	    return true;
	  }
	  
	}
