import type { SimpleAttributes, SQLNode } from "./types.js";

/**
 * The WhereClause is used to extract the features that meet a specified condition by parsing the provided
 * results in to a value. The [parseWhereClause()](https://developers.arcgis.com/javascript/latest/references/core/core/sql/#parseWhereClause) method
 * returns a Promise that resolves to an instance of this module.
 *
 * @since 4.14
 * @see [Standardized SQL functions in ArcGIS Online](https://doc.arcgis.com/en/arcgis-online/reference/sql-agol.htm)
 */
export default abstract class WhereClause {
  /**
   * An array of the field names used in the where clause. It can be used
   * to get the appropriate fields when querying layers.
   *
   * @example
   * // parse layer's definition expression into where clause object
   * sql.parseWhereClause(layer.definitionExpression, layer.fieldsIndex)
   * .then(function(clause){
   *   layer.queryFeatures({
   *     where: "1=1",
   *     // where clause object returns layer fields
   *     // use these fields to query features from the layer
   *     outFields: clause.fieldsNames
   *   }).then(function(results) {
   *    // process query results
   *   });
   * });
   */
  get fieldNames(): string[];
  /** Returns `true` if the parsed where clause meets the requirements of standardized sql. */
  readonly isStandardized: boolean;
  /**
   * A parse tree is a data structure for representing a parsed sql statement. Parsing a statement requires
   * the grammar of the language that the statement was written.
   *
   * @since 4.24
   * @see [Enforce standardized SQL queries](https://enterprise.arcgis.com/en/server/latest/administer/linux/about-standardized-queries.htm)
   * @see [SQL reference for query expressions used in ArcGIS](https://pro.arcgis.com/en/pro-app/latest/help/mapping/navigation/sql-reference-for-elements-used-in-query-expressions.htm)
   */
  readonly parseTree: SQLNode;
  /**
   * Executes the where clause against a feature to generate a value. It is used when the `WhereClause` is being
   * used as a simple expression. For example, you can use the expression to gather values for statistics.
   *
   * @param feature - The feature to check against the where clause.
   * @returns Returns a value after check feature against the provided where clause. Returns  `null` if the
   * provided value is unknown.
   * @example
   * // calculate the grand total sales price of all features
   * featureLayer.queryFeatures().then(function(results){
   *   let total;
   *   const expression = "totalSales * totalPrice";
   *   sql.parseWhereClause(expression, layer.fieldsIndex)
   *   .then(function(whereClause){
   *     // check if the where clause meets requirements of standardized sql
   *     if (whereClause.isStandardized){
   *       features.forEach(function(feature){
   *         total += whereClause.calculateValue(feature)
   *       });
   *       console.log(total); // prints the total sales price of all features
   *     }
   *   });
   * });
   */
  calculateValue(feature: SimpleAttributes): any;
  /**
   * Tests the attributes of a feature against the `whereClause`, and returns `true` if the test passes, `false` otherwise.
   *
   * @param feature - The feature to test against the `whereClause`.
   * @returns Returns `true` if the test passes, `false` otherwise.
   * @example
   * sql.parseWhereClause("POPULATION > 100000", layer.fieldsIndex)
   * .then(function(clause){
   *   let testResult = clause.testFeature(new Graphic({
   *     attributes: {
   *       POPULATION: 300000
   *    }
   *  });
   *  console.log(testResult); // prints true
   * });
   */
  testFeature(feature: SimpleAttributes): boolean;
}