// Copyright (C) 2013 The Android Open Source Project
//
// Licensed 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 com.google.gerrit.lucene;

import static org.apache.lucene.search.BooleanClause.Occur.MUST;
import static org.apache.lucene.search.BooleanClause.Occur.MUST_NOT;
import static org.apache.lucene.search.BooleanClause.Occur.SHOULD;

import com.google.common.collect.Lists;
import com.google.gerrit.server.index.ChangeField;
import com.google.gerrit.server.index.FieldType;
import com.google.gerrit.server.index.IndexPredicate;
import com.google.gerrit.server.index.IntegerRangePredicate;
import com.google.gerrit.server.index.RegexPredicate;
import com.google.gerrit.server.index.Schema;
import com.google.gerrit.server.index.TimestampRangePredicate;
import com.google.gerrit.server.query.AndPredicate;
import com.google.gerrit.server.query.NotPredicate;
import com.google.gerrit.server.query.OrPredicate;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.SortKeyPredicate;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.NumericUtils;

import java.util.Date;
import java.util.List;

public class QueryBuilder {
  private static final String ID_FIELD = ChangeField.LEGACY_ID.getName();

  public static Term idTerm(ChangeData cd) {
    return intTerm(ID_FIELD, cd.getId().get());
  }

  public static Term idTerm(int id) {
    return intTerm(ID_FIELD, id);
  }

  private final Schema<ChangeData> schema;
  private final org.apache.lucene.util.QueryBuilder queryBuilder;

  public QueryBuilder(Schema<ChangeData> schema, Analyzer analyzer) {
    this.schema = schema;
    queryBuilder = new org.apache.lucene.util.QueryBuilder(analyzer);
  }

  public Query toQuery(Predicate<ChangeData> p) throws QueryParseException {
    if (p instanceof AndPredicate) {
      return and(p);
    } else if (p instanceof OrPredicate) {
      return or(p);
    } else if (p instanceof NotPredicate) {
      return not(p);
    } else if (p instanceof IndexPredicate) {
      return fieldQuery((IndexPredicate<ChangeData>) p);
    } else {
      throw new QueryParseException("cannot create query for index: " + p);
    }
  }

  private Query or(Predicate<ChangeData> p)
      throws QueryParseException {
    try {
      BooleanQuery q = new BooleanQuery();
      for (int i = 0; i < p.getChildCount(); i++) {
        q.add(toQuery(p.getChild(i)), SHOULD);
      }
      return q;
    } catch (BooleanQuery.TooManyClauses e) {
      throw new QueryParseException("cannot create query for index: " + p, e);
    }
  }

  private Query and(Predicate<ChangeData> p)
      throws QueryParseException {
    try {
      BooleanQuery b = new BooleanQuery();
      List<Query> not = Lists.newArrayListWithCapacity(p.getChildCount());
      for (int i = 0; i < p.getChildCount(); i++) {
        Predicate<ChangeData> c = p.getChild(i);
        if (c instanceof NotPredicate) {
          Predicate<ChangeData> n = c.getChild(0);
          if (n instanceof TimestampRangePredicate) {
            b.add(notTimestamp((TimestampRangePredicate<ChangeData>) n), MUST);
          } else {
            not.add(toQuery(n));
          }
        } else {
          b.add(toQuery(c), MUST);
        }
      }
      for (Query q : not) {
        b.add(q, MUST_NOT);
      }
      return b;
    } catch (BooleanQuery.TooManyClauses e) {
      throw new QueryParseException("cannot create query for index: " + p, e);
    }
  }

  private Query not(Predicate<ChangeData> p)
      throws QueryParseException {
    Predicate<ChangeData> n = p.getChild(0);
    if (n instanceof TimestampRangePredicate) {
      return notTimestamp((TimestampRangePredicate<ChangeData>) n);
    }

    // Lucene does not support negation, start with all and subtract.
    BooleanQuery q = new BooleanQuery();
    q.add(new MatchAllDocsQuery(), MUST);
    q.add(toQuery(n), MUST_NOT);
    return q;
  }

  private Query fieldQuery(IndexPredicate<ChangeData> p)
      throws QueryParseException {
    if (p.getType() == FieldType.INTEGER) {
      return intQuery(p);
    } else if (p.getType() == FieldType.INTEGER_RANGE) {
      return intRangeQuery(p);
    } else if (p.getType() == FieldType.TIMESTAMP) {
      return timestampQuery(p);
    } else if (p.getType() == FieldType.EXACT) {
      return exactQuery(p);
    } else if (p.getType() == FieldType.PREFIX) {
      return prefixQuery(p);
    } else if (p.getType() == FieldType.FULL_TEXT) {
      return fullTextQuery(p);
    } else if (p instanceof SortKeyPredicate) {
      return sortKeyQuery((SortKeyPredicate) p);
    } else {
      throw badFieldType(p.getType());
    }
  }

  private static Term intTerm(String name, int value) {
    BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT);
    NumericUtils.intToPrefixCodedBytes(value, 0, bytes);
    return new Term(name, bytes);
  }

  private Query intQuery(IndexPredicate<ChangeData> p)
      throws QueryParseException {
    int value;
    try {
      // Can't use IntPredicate because it and IndexPredicate are different
      // subclasses of OperatorPredicate.
      value = Integer.valueOf(p.getValue());
    } catch (IllegalArgumentException e) {
      throw new QueryParseException("not an integer: " + p.getValue());
    }
    return new TermQuery(intTerm(p.getField().getName(), value));
  }

  private Query intRangeQuery(IndexPredicate<ChangeData> p)
      throws QueryParseException {
    if (p instanceof IntegerRangePredicate) {
      IntegerRangePredicate<ChangeData> r =
          (IntegerRangePredicate<ChangeData>) p;
      int minimum = r.getMinimumValue();
      int maximum = r.getMaximumValue();
      if (minimum == maximum) {
        // Just fall back to a standard integer query.
        return new TermQuery(intTerm(p.getField().getName(), minimum));
      } else {
        return NumericRangeQuery.newIntRange(
            r.getField().getName(),
            minimum,
            maximum,
            true,
            true);
      }
    }
    throw new QueryParseException("not an integer range: " + p);
  }

  private Query sortKeyQuery(SortKeyPredicate p) {
    long min = p.getMinValue(schema);
    long max = p.getMaxValue(schema);
    return NumericRangeQuery.newLongRange(
        p.getField().getName(),
        min != Long.MIN_VALUE ? min : null,
        max != Long.MAX_VALUE ? max : null,
        false, false);
  }

  @SuppressWarnings("deprecation")
  private Query timestampQuery(IndexPredicate<ChangeData> p)
      throws QueryParseException {
    if (p instanceof TimestampRangePredicate) {
      TimestampRangePredicate<ChangeData> r =
          (TimestampRangePredicate<ChangeData>) p;
      if (r.getField() == ChangeField.LEGACY_UPDATED) {
        return NumericRangeQuery.newIntRange(
            r.getField().getName(),
            toIndexTimeInMinutes(r.getMinTimestamp()),
            toIndexTimeInMinutes(r.getMaxTimestamp()),
            true, true);
      } else {
        return NumericRangeQuery.newLongRange(
            r.getField().getName(),
            r.getMinTimestamp().getTime(),
            r.getMaxTimestamp().getTime(),
            true, true);
      }
    }
    throw new QueryParseException("not a timestamp: " + p);
  }

  @SuppressWarnings("deprecation")
  private Query notTimestamp(TimestampRangePredicate<ChangeData> r)
      throws QueryParseException {
    if (r.getMinTimestamp().getTime() == 0) {
      if (r.getField() == ChangeField.LEGACY_UPDATED) {
        return NumericRangeQuery.newIntRange(
            r.getField().getName(),
            toIndexTimeInMinutes(r.getMaxTimestamp()),
            null,
            true, true);
      } else {
        return NumericRangeQuery.newLongRange(
            r.getField().getName(),
            r.getMaxTimestamp().getTime(),
            null,
            true, true);
      }
    }
    throw new QueryParseException("cannot negate: " + r);
  }

  private Query exactQuery(IndexPredicate<ChangeData> p) {
    if (p instanceof RegexPredicate<?>) {
      return regexQuery(p);
    } else {
      return new TermQuery(new Term(p.getField().getName(), p.getValue()));
    }
  }

  private Query regexQuery(IndexPredicate<ChangeData> p) {
    String re = p.getValue();
    if (re.startsWith("^")) {
      re = re.substring(1);
    }
    if (re.endsWith("$") && !re.endsWith("\\$")) {
      re = re.substring(0, re.length() - 1);
    }
    return new RegexpQuery(new Term(p.getField().getName(), re));
  }

  private Query prefixQuery(IndexPredicate<ChangeData> p) {
    return new PrefixQuery(new Term(p.getField().getName(), p.getValue()));
  }

  private Query fullTextQuery(IndexPredicate<ChangeData> p) {
    return queryBuilder.createPhraseQuery(p.getField().getName(), p.getValue());
  }

  public int toIndexTimeInMinutes(Date ts) {
    return (int) (ts.getTime() / 60000);
  }

  public static IllegalArgumentException badFieldType(FieldType<?> t) {
    return new IllegalArgumentException("unknown index field type " + t);
  }
}
