/*
 * 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.solr.search;

import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.queries.function.FunctionQuery;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.ConstValueSource;
import org.apache.lucene.queries.function.valuesource.DoubleConstValueSource;
import org.apache.lucene.queries.function.valuesource.LiteralValueSource;
import org.apache.lucene.queries.function.valuesource.QueryValueSource;
import org.apache.lucene.queries.function.valuesource.VectorValueSource;
import org.apache.lucene.search.Query;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.facet.AggValueSource;
import org.apache.solr.search.function.FieldNameValueSource;

public class FunctionQParser extends QParser {

  public static final int FLAG_CONSUME_DELIMITER = 0x01;  // consume delimiter after parsing arg
  public static final int FLAG_IS_AGG = 0x02;
  public static final int FLAG_USE_FIELDNAME_SOURCE = 0x04; // When a field name is encountered, use the placeholder FieldNameValueSource instead of resolving to a real ValueSource
  public static final int FLAG_DEFAULT = FLAG_CONSUME_DELIMITER;

  /** @lucene.internal */
  public StrParser sp;
  boolean parseMultipleSources = true;
  boolean parseToEnd = true;

  public FunctionQParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
    super(qstr, localParams, params, req);
    setString(qstr);
  }

  @Override
  public void setString(String s) {
    super.setString(s);
    if (s != null) {
      sp = new StrParser( s );
    }
  }

  public void setParseMultipleSources(boolean parseMultipleSources) {
    this.parseMultipleSources = parseMultipleSources;  
  }

  /** parse multiple comma separated value sources */
  public boolean getParseMultipleSources() {
    return parseMultipleSources;
  }

  public void setParseToEnd(boolean parseToEnd) {
    this.parseToEnd = parseToEnd;
  }

  /** throw exception if there is extra stuff at the end of the parsed valuesource(s). */
  public boolean getParseToEnd() {
    return parseMultipleSources;
  }

  @Override
  public Query parse() throws SyntaxError {
    ValueSource vs = null;
    List<ValueSource> lst = null;

    for(;;) {
      ValueSource valsource = parseValueSource(FLAG_DEFAULT & ~FLAG_CONSUME_DELIMITER);
      sp.eatws();
      if (!parseMultipleSources) {
        vs = valsource; 
        break;
      } else {
        if (lst != null) {
          lst.add(valsource);
        } else {
          vs = valsource;
        }
      }

      // check if there is a "," separator
      if (sp.peek() != ',') break;

      consumeArgumentDelimiter();

      if (lst == null) {
        lst = new ArrayList<>(2);
        lst.add(valsource);
      }
    }

    if (parseToEnd && sp.pos < sp.end) {
      throw new SyntaxError("Unexpected text after function: " + sp.val.substring(sp.pos, sp.end));
    }

    if (lst != null) {
      vs = new VectorValueSource(lst);
    }

    return new FunctionQuery(vs);
  }

  /**
   * Are there more arguments in the argument list being parsed?
   * 
   * @return whether more args exist
   */
  public boolean hasMoreArguments() throws SyntaxError {
    int ch = sp.peek();
    /* determine whether the function is ending with a paren or end of str */
    return (! (ch == 0 || ch == ')') );
  }
  
  /*
   * TODO: Doc
   */
  public String parseId() throws SyntaxError {
    String value = parseArg();
    if (argWasQuoted()) {
      throw new SyntaxError("Expected identifier instead of quoted string:" + value);
    } else if (value == null) {
      throw new SyntaxError("Expected identifier instead of 'null' for function "  + sp);
    }
    return value;
  }
  
  /**
   * Parse a float.
   * 
   * @return Float
   */
  public Float parseFloat() throws SyntaxError {
    String str = parseArg();
    if (argWasQuoted()) throw new SyntaxError("Expected float instead of quoted string:" + str);
    try {
      return Float.parseFloat(str);
    } catch (NumberFormatException | NullPointerException e) {
      throw new SyntaxError("Expected float instead of '" + str + "' for function "  + sp);
    }
  }

  /**
   * Parse a Double
   * @return double
   */
  public double parseDouble() throws SyntaxError {
    String str = parseArg();
    if (argWasQuoted()) throw new SyntaxError("Expected double instead of quoted string:" + str);
    try {
      return Double.parseDouble(str);
    } catch (NumberFormatException | NullPointerException e) {
      throw new SyntaxError("Expected double instead of '" + str + "' for function " + sp);
    }
  }

  /**
   * Parse an integer
   * @return An int
   */
  public int parseInt() throws SyntaxError {
    String str = parseArg();
    if (argWasQuoted()) throw new SyntaxError("Expected integer instead of quoted string:" + str);
    try {
      return Integer.parseInt(str);
    } catch (NumberFormatException | NullPointerException e) {
      throw new SyntaxError("Expected integer instead of '" + str + "' for function "  + sp);
    }
  }


  private boolean argWasQuoted;
  public boolean argWasQuoted() {
    return argWasQuoted;
  }

  public String parseArg() throws SyntaxError {
    argWasQuoted = false;

    sp.eatws();
    char ch = sp.peek();
    String val = null;
    switch (ch) {
      case ')': return null;
      case '$':
        sp.pos++;
        String param = sp.getId();
        val = getParam(param);
        break;
      case '\'':
      case '"':
        val = sp.getQuotedString();
        argWasQuoted = true;
        break;
      default:
        // read unquoted literal ended by whitespace ',' or ')'
        // there is no escaping.
        int valStart = sp.pos;
        for (;;) {
          if (sp.pos >= sp.end) {
            throw new SyntaxError("Missing end to unquoted value starting at " + valStart + " str='" + sp.val +"'");
          }
          char c = sp.val.charAt(sp.pos);
          if (c==')' || c==',' || Character.isWhitespace(c)) {
            val = sp.val.substring(valStart, sp.pos);
            break;
          }
          sp.pos++;
        }
    }

    sp.eatws();
    consumeArgumentDelimiter();
    return val;
  }

  
  /**
   * Parse a list of ValueSource.  Must be the final set of arguments
   * to a ValueSource.
   * 
   * @return List&lt;ValueSource&gt;
   */
  public List<ValueSource> parseValueSourceList() throws SyntaxError {
    List<ValueSource> sources = new ArrayList<>(3);
    while (hasMoreArguments()) {
      sources.add(parseValueSource(FLAG_DEFAULT | FLAG_CONSUME_DELIMITER));
    }
    return sources;
  }

  /**
   * Parse an individual ValueSource.
   */
  public ValueSource parseValueSource() throws SyntaxError {
    /* consume the delimiter afterward for an external call to parseValueSource */
    return parseValueSource(FLAG_DEFAULT | FLAG_CONSUME_DELIMITER);
  }
  
  /*
   * TODO: Doc
   */
  public Query parseNestedQuery() throws SyntaxError {
    Query nestedQuery;
    
    if (sp.opt("$")) {
      String param = sp.getId();
      String qstr = getParam(param);
      qstr = qstr==null ? "" : qstr;
      nestedQuery = subQuery(qstr, null).getQuery();

      // nestedQuery would be null when de-referenced query value is not specified
      // Ex: query($qq) in request with no qq param specified
      if (nestedQuery == null) {
        throw new SyntaxError("Missing param " + param + " while parsing function '" + sp.val + "'");
      }
    }
    else {
      int start = sp.pos;
      String v = sp.val;
  
      String qs = v;
      ModifiableSolrParams nestedLocalParams = new ModifiableSolrParams();
      int end = QueryParsing.parseLocalParams(qs, start, nestedLocalParams, getParams());
  
      QParser sub;
  
      if (end>start) {
        if (nestedLocalParams.get(QueryParsing.V) != null) {
          // value specified directly in local params... so the end of the
          // query should be the end of the local params.
          sub = subQuery(qs.substring(start, end), null);
        } else {
          // value here is *after* the local params... ask the parser.
          sub = subQuery(qs, null);
          // int subEnd = sub.findEnd(')');
          // TODO.. implement functions to find the end of a nested query
          throw new SyntaxError("Nested local params must have value in v parameter.  got '" + qs + "'");
        }
      } else {
        throw new SyntaxError("Nested function query must use $param or {!v=value} forms. got '" + qs + "'");
      }
  
      sp.pos += end-start;  // advance past nested query
      nestedQuery = sub.getQuery();
      // handling null check on nestedQuery separately, so that proper error can be returned
      // one case this would be possible when v is specified but v's value is empty or has only spaces
      if (nestedQuery == null) {
        throw new SyntaxError("Nested function query returned null for '" + sp.val + "'");
      }
    }
    consumeArgumentDelimiter();

    return nestedQuery;
  }

  /**
   * Parse an individual value source.
   * 
   * @param doConsumeDelimiter whether to consume a delimiter following the ValueSource  
   */
   protected ValueSource parseValueSource(boolean doConsumeDelimiter) throws SyntaxError {
     return parseValueSource( doConsumeDelimiter ? (FLAG_DEFAULT | FLAG_CONSUME_DELIMITER) : (FLAG_DEFAULT & ~FLAG_CONSUME_DELIMITER) );
   }

   protected ValueSource parseValueSource(int flags) throws SyntaxError {
    ValueSource valueSource;
    
    int ch = sp.peek();
    if (ch>='0' && ch<='9'  || ch=='.' || ch=='+' || ch=='-') {
      Number num = sp.getNumber();
      if (num instanceof Long) {
        valueSource = new ValueSourceParser.LongConstValueSource(num.longValue());
      } else if (num instanceof Double) {
        valueSource = new DoubleConstValueSource(num.doubleValue());
      } else {
        // shouldn't happen
        valueSource = new ConstValueSource(num.floatValue());
      }
    } else if (ch == '"' || ch == '\''){
      valueSource = new LiteralValueSource(sp.getQuotedString());
    } else if (ch == '$') {
      sp.pos++;
      String param = sp.getId();
      String val = getParam(param);
      if (val == null) {
        throw new SyntaxError("Missing param " + param + " while parsing function '" + sp.val + "'");
      }

      QParser subParser = subQuery(val, "func");
      if (subParser instanceof FunctionQParser) {
        ((FunctionQParser)subParser).setParseMultipleSources(true);
      }
      Query subQuery = subParser.getQuery();
      if (subQuery instanceof FunctionQuery) {
        valueSource = ((FunctionQuery) subQuery).getValueSource();
      } else {
        valueSource = new QueryValueSource(subQuery, 0.0f);
      }

      /***
       // dereference *simple* argument (i.e., can't currently be a function)
       // In the future we could support full function dereferencing via a stack of ValueSource (or StringParser) objects
      ch = val.length()==0 ? '\0' : val.charAt(0);

      if (ch>='0' && ch<='9'  || ch=='.' || ch=='+' || ch=='-') {
        StrParser sp = new StrParser(val);
        Number num = sp.getNumber();
        if (num instanceof Long) {
          valueSource = new LongConstValueSource(num.longValue());
        } else if (num instanceof Double) {
          valueSource = new DoubleConstValueSource(num.doubleValue());
        } else {
          // shouldn't happen
          valueSource = new ConstValueSource(num.floatValue());
        }
      } else if (ch == '"' || ch == '\'') {
        StrParser sp = new StrParser(val);
        val = sp.getQuotedString();
        valueSource = new LiteralValueSource(val);
      } else {
        if (val.length()==0) {
          valueSource = new LiteralValueSource(val);
        } else {
          String id = val;
          SchemaField f = req.getSchema().getField(id);
          valueSource = f.getType().getValueSource(f, this);
        }
      }
       ***/

    } else {

      String id = sp.getId();
      if (sp.opt("(")) {
        // a function... look it up.
        ValueSourceParser argParser = req.getCore().getValueSourceParser(id);
        if (argParser==null) {
          throw new SyntaxError("Unknown function " + id + " in FunctionQuery(" + sp + ")");
        }
        valueSource = argParser.parse(this);
        sp.expect(")");
      } else {
        if ("true".equals(id)) {
          valueSource = ValueSourceParser.BoolConstValueSource.TRUE;
        } else if ("false".equals(id)) {
          valueSource = ValueSourceParser.BoolConstValueSource.FALSE;
        } else {
          if ((flags & FLAG_USE_FIELDNAME_SOURCE) != 0) {
            // Don't try to create a ValueSource for the field, just use a placeholder.
            valueSource = new FieldNameValueSource(id);
          } else {
            SchemaField f = req.getSchema().getField(id);
            valueSource = f.getType().getValueSource(f, this);
          }
        }
      }

    }
    
    if ((flags & FLAG_CONSUME_DELIMITER) != 0) {
      consumeArgumentDelimiter();
    }
    
    return valueSource;
  }

  /** @lucene.experimental */
  public AggValueSource parseAgg(int flags) throws SyntaxError {
    String origId = sp.getId();
    AggValueSource vs = null;
    boolean hasParen;

    if ("agg".equals(origId)) {
      hasParen = sp.opt("(");
      vs = parseAgg(flags | FLAG_IS_AGG);
    } else {
      // parse as an aggregation...
      String id = origId.startsWith("agg_")? origId: "agg_" + origId;
      hasParen = sp.opt("(");

      ValueSourceParser argParser = req.getCore().getValueSourceParser(id);
      if (argParser == null) {
        argParser = req.getCore().getValueSourceParser(origId);
        if (argParser == null) {
          throw new SyntaxError("Unknown aggregation '" + origId + "' in input (" + sp + ")");
        } else {
          throw new SyntaxError("Expected multi-doc aggregation from '" +  origId +
              "' but got per-doc function in input (" + sp + ")");
        }
      }

      ValueSource vv = argParser.parse(this);
      if (!(vv instanceof AggValueSource)) {
        throw new SyntaxError("Expected multi-doc aggregation from '" + origId +
            "' but got (" + vv + ") in (" + sp + ")");
      }
      vs = (AggValueSource) vv;
    }

    if (hasParen) {
      sp.expect(")");
    }

    if ((flags & FLAG_CONSUME_DELIMITER) != 0) {
      consumeArgumentDelimiter();
    }

    return vs;
  }


  /**
   * Consume an argument delimiter (a comma) from the token stream.
   * Only consumes if more arguments should exist (no ending parens or end of string).
   * 
   * @return whether a delimiter was consumed
   */
  protected boolean consumeArgumentDelimiter() throws SyntaxError {
    /* if a list of args is ending, don't expect the comma */
    if (hasMoreArguments()) {
      sp.expect(",");
      return true;
    }
   
    return false;
  }
    

}
