/*
 * 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.drill.exec.store.splunk;

import org.apache.drill.common.expression.SchemaPath;
import org.apache.drill.exec.store.base.filter.ExprNode;
import org.apache.drill.exec.store.base.filter.RelOp;
import com.google.common.base.Strings;

import java.util.Map;

public class SplunkQueryBuilder {
  public final static String EQUAL_OPERATOR = "=";
  public final static String NOT_EQUAL_OPERATOR = "!=";
  public final static String GREATER_THAN = ">";
  public final static String GREATER_THAN_EQ = ">=";
  public final static String LESS_THAN = "<";
  public final static String LESS_THAN_EQ = "<=";

  private String query;
  private String sourceTypes;
  private String concatenatedFields;
  private String filters;
  private int sourcetypeCount;
  private int limit;

  public SplunkQueryBuilder (String index) {
    this.filters = "";
    sourcetypeCount = 0;
    query = "search index=" + index;
  }

  /**
   * Adds a sourcetype to the Splunk query.  Splunk indexes its data by indexes, then within the index, organizes
   * the data by sourcetype, which could be a reference to the underlying source system.  For instance, sourcetype
   * might be csv files, log files, Azure storage or whatever.  Since this is a sort of special metadata case,
   * it is better to apply this separately than a regular filter.  Sourcetypes can accept wildcards, but cannot accept
   * any other operator other than = or !=.
   * @param sourceType The Splunk Sourcetype to be added to the Splunk query.
   */
  public void addSourceType(String sourceType) {
    if (this.sourceTypes == null) {
      this.sourceTypes = " sourcetype=\"" + sourceType + "\"";
    } else if (! sourceTypes.contains("sourcetype=\"" + sourceType + "\"")) {
      this.sourceTypes += " OR sourcetype=\"" + sourceType + "\"";
    }
    sourcetypeCount++;
  }

  /**
   * Adds a field name to a Splunk query.  To push down the projection into Splunk,
   * Splunk accepts arguments in the format | fields foo, bar, car.  This function adds these fields to the query.
   * As an error preventative measure, this function will ignore ** from Drill.
   * @param field The field to be added to the query
   * @return true if the field was added, false if it was skipped
   */
  public boolean addField(String field) {
    // Double Star fields cause errors and we will not add to the field list
    if (SchemaPath.DYNAMIC_STAR.equals(field) || SplunkUtils.SPECIAL_FIELDS.includes(field)) {
      return false;
    }

    // Case for first field
    if (concatenatedFields == null) {
      this.concatenatedFields = field;
    } else {
      this.concatenatedFields += "," + field;
    }
    return true;
  }

  /**
   * Adds a row limit to the query. Ignores anything <= zero.
   * This method should only be called once, but if is called more than once,
   * it will set the limit to the most recent value.
   * @param limit Positive, non-zero integer of number of desired rows.
   */
  public void addLimit(int limit) {
    if (limit > 0) {
      this.limit = limit;
    }
  }

  /**
   * Adds a filter to the Splunk query.  Splunk treats all filters as
   * AND filters, without explicitly noting that.  The operator should be the actual operator
   * @param left The field to be filtered
   * @param right The value of that field
   * @param operator The actual operator to go in the SPL query
   */
  public void addFilter(String left, String right, String operator) {
    filters = filters + " " + left + operator + quoteString(right);
  }

  /**
   * Adds an isnotnull() filter to the Splunk query
   * @param fieldName The field name which should be null
   */
  public void addNotNullFilter(String fieldName) {
    filters = filters + " isnotnull(" + fieldName + ") ";
  }

  /**
   * Adds an isnull() filter to the Splunk query
   * @param fieldName The field name which should be null
   */
  public void addNullFilter(String fieldName) {
    filters = filters + " isnull(" + fieldName + ") ";
  }

  /**
   * Processes the filters for a Splunk query
   * @param filters A HashMap of filters
   */
  public void addFilters(Map<String, ExprNode.ColRelOpConstNode> filters) {
    if (filters == null) {
      return;
    }
    for ( Map.Entry filter : filters.entrySet()) {
      String fieldName = ((ExprNode.ColRelOpConstNode)filter.getValue()).colName;
      RelOp operation = ((ExprNode.ColRelOpConstNode)filter.getValue()).op;
      String value = ((ExprNode.ColRelOpConstNode)filter.getValue()).value.value.toString();

      // Ignore special cases
      if (SplunkUtils.SPECIAL_FIELDS.includes(fieldName)) {
        // Sourcetypes are a special case and can be added via filter pushdown
        if (fieldName.equalsIgnoreCase("sourcetype")) {
          addSourceType(value);
        }
        continue;
      }

      switch (operation) {
        case EQ:
          // Sourcetypes are a special case and can be added via filter pushdown
          if (fieldName.equalsIgnoreCase("sourcetype")) {
            addSourceType(value);
          } else {
            addFilter(fieldName, value, EQUAL_OPERATOR);
          }
          break;
        case NE:
          addFilter(fieldName, value, NOT_EQUAL_OPERATOR);
          break;
        case GE:
          addFilter(fieldName, value, GREATER_THAN_EQ);
          break;
        case GT:
          addFilter(fieldName, value, GREATER_THAN);
          break;
        case LE:
          addFilter(fieldName, value, LESS_THAN_EQ);
          break;
        case LT:
          addFilter(fieldName, value, LESS_THAN);
          break;
        case IS_NULL:
          addNullFilter(fieldName);
          break;
        case IS_NOT_NULL:
          addNotNullFilter(fieldName);
          break;
      }
    }
  }

  /**
   * Adds quotes around text for use in SPL queries. Ignores numbers
   * @param word The input word to be quoted.
   * @return The text with quotes
   */
  public String quoteString(String word) {

    if (! isNumeric(word)) {
      return "\"" + word + "\"";
    } else {
      return word;
    }
  }

  public String build() {
    // Add the sourcetype
    if (! Strings.isNullOrEmpty(sourceTypes)) {

      // Add parens
      if (sourcetypeCount > 1) {
        sourceTypes = " (" + sourceTypes.trim() + ")";
      }
      query += sourceTypes;
    }

    // Add filters
    if (! Strings.isNullOrEmpty(filters)) {
      query += filters;
    }

    // Add fields
    if (! Strings.isNullOrEmpty(concatenatedFields)) {
      query += " | fields " + concatenatedFields;
    }

    // Add limit
    if (this.limit > 0) {
      query += " | head " + this.limit;
    }

    // Add table logic. This tells Splunk to return the data in tabular form rather than the mess that it usually generates
    if ( Strings.isNullOrEmpty(concatenatedFields)) {
      concatenatedFields = "*";
    }
    query += " | table " + concatenatedFields;

    return query;
  }

  /**
   * Returns true if the given string is numeric, false if not
   * @param str The string to test for numeric
   * @return True if the string is numeric, false if not.
   */
  public static boolean isNumeric(String str)
  {
    return str.matches("-?\\d+(\\.\\d+)?");
  }
}
