package org.lumongo.server.indexing;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.lumongo.server.config.IndexConfig;

public class LumongoQueryParser extends QueryParser {
	
	private static final DateTimeFormatter dateFormatter = ISODateTimeFormat.dateTimeNoMillis();
	
	private IndexConfig indexConfig;
	
	public LumongoQueryParser(Analyzer analyzer, IndexConfig indexConfig) {
		super(indexConfig.getDefaultSearchField(), analyzer);
		this.indexConfig = indexConfig;
		setAllowLeadingWildcard(true);
	}
	
	public void setField(String field) {
		if (field == null) {
			throw new IllegalArgumentException("Field can not be null");
		}
		this.field = field;
	}
	
	@Override
	protected Query getRangeQuery(String field, String start, String end, boolean startInclusive, boolean endInclusive) throws ParseException {
		
		if (indexConfig.isNumericOrDateField(field)) {
			return getNumericOrDateRange(field, start, end, startInclusive, endInclusive);
		}
		
		return super.getRangeQuery(field, start, end, startInclusive, endInclusive);
		
	}
	
	private NumericRangeQuery<?> getNumericOrDateRange(final String fieldName, final String start, final String end, final boolean startInclusive,
					final boolean endInclusive) {
		if (indexConfig.isNumericIntField(fieldName)) {
			return NumericRangeQuery.newIntRange(fieldName, Integer.parseInt(start), Integer.parseInt(end), startInclusive, endInclusive);
		}
		else if (indexConfig.isNumericLongField(fieldName)) {
			return NumericRangeQuery.newLongRange(fieldName, Long.parseLong(start), Long.parseLong(end), startInclusive, endInclusive);
		}
		else if (indexConfig.isNumericFloatField(fieldName)) {
			return NumericRangeQuery.newFloatRange(fieldName, Float.parseFloat(start), Float.parseFloat(end), startInclusive, endInclusive);
		}
		else if (indexConfig.isNumericDoubleField(fieldName)) {
			return NumericRangeQuery.newDoubleRange(fieldName, Double.parseDouble(start), Double.parseDouble(end), startInclusive, endInclusive);
		}
		else if (indexConfig.isDateField(fieldName)) {
			DateTime startDate = dateFormatter.parseDateTime(start);
			DateTime endDate = dateFormatter.parseDateTime(end);
			
			return NumericRangeQuery.newLongRange(fieldName, startDate.toDate().getTime(), endDate.toDate().getTime(), startInclusive, endInclusive);
		}
		throw new RuntimeException("Not a valid numeric field <" + fieldName + ">");
	}
	
	@Override
	protected Query newTermQuery(org.apache.lucene.index.Term term) {
		String field = term.field();
		String text = term.text();
		
		if (indexConfig.isNumericOrDateField(field)) {
			return getNumericOrDateRange(field, text, text, true, true);
		}
		
		return super.newTermQuery(term);
	}
}

@@ -1660,16 +1660,39 @@
 eldName,
+ start == null ? null :
  Integer
@@ -1708,16 +1708,37 @@
 (start),
+ end == null ? null :
  Integer
@@ -1748,25 +1748,32 @@
 rseInt(end),
- 
+%0A%09%09%09%09%09%09%09
 startInclusi
@@ -1902,16 +1902,39 @@
 eldName,
+ start == null ? null :
  Long.pa
@@ -1948,16 +1948,37 @@
 (start),
+ end == null ? null :
  Long.pa
@@ -1986,25 +1986,32 @@
 seLong(end),
- 
+%0A%09%09%09%09%09%09%09
 startInclusi
@@ -2142,16 +2142,39 @@
 eldName,
+ start == null ? null :
  Float.p
@@ -2190,16 +2190,37 @@
 (start),
+ end == null ? null :
  Float.p
@@ -2230,25 +2230,32 @@
 eFloat(end),
- 
+%0A%09%09%09%09%09%09%09
 startInclusi
@@ -2388,16 +2388,39 @@
 eldName,
+ start == null ? null :
  Double.
@@ -2438,16 +2438,37 @@
 (start),
+ end == null ? null :
  Double.
@@ -2484,17 +2484,24 @@
 le(end),
- 
+%0A%09%09%09%09%09%09%09
 startInc
@@ -2583,65 +2583,214 @@
 %0A%09%09%09
-DateTime startDate = dateFormatter.parseDateTime(start);%0A
+Long startTime = null;%0A%09%09%09Long endTime = null;%0A%09%09%09if (start != null) %7B%0A%09%09%09%09DateTime startDate = dateFormatter.parseDateTime(start);%0A%09%09%09%09startTime = startDate.toDate().getTime();%0A%09%09%09%7D%0A%09%09%09if (end != null) %7B%0A%09
 %09%09%09D
@@ -2844,16 +2844,59 @@
 nd);%0A%09%09%09
+%09endTime = endDate.toDate().getTime();%0A%09%09%09%7D
 %0A%09%09%09retu
@@ -2949,59 +2949,21 @@
 tart
-Date.toDate().get
 Time
-()
 , end
-Date.toDate().get
 Time
-()
 , st

fix date range in lumongo