import type GraphSearch from "./GraphSearch.js";
import type { GraphSearchProperties } from "./GraphSearch.js";

export interface GraphSearchStreamingProperties extends GraphSearchProperties, Partial<Pick<GraphSearchStreaming, "idsFilter" | "namedTypesFilter" | "num" | "returnSearchContext" | "start">> {}

/**
 * The search operation is performed on a knowledge graph service's
 * [graph](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-knowledgeGraph-KnowledgeGraph.html) resource.
 * This operation allows you to search the properties of both {@link rest/knowledgeGraph/Entities} and
 * {@link rest/knowledgeGraph/Relationships} in the graph.
 * Any field with the `text` data type or the [Globally Unique Identifier (GUID)](https://pro.arcgis.com/en/pro-app/latest/help/data/geodatabases/overview/arcgis-field-data-types.htm#GUID-97064FAE-B42E-4DC3-A5C9-9A6F12D053A8) data type with the
 * {@link rest/knowledgeGraph/GraphProperty#searchable} properties set to `true` is included in the search.
 * A search index is built and maintained automatically on the values for all searchable fields.
 *
 * Streaming search returns the [result](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-knowledgeGraph-GraphQueryStreamingResult.html) faster than search and in small chunks that can be rendered immediately.
 * Streaming search also provides additional parameters to constrain the search.
 *
 * @since 4.25
 * @see [Sample - Search a knowledge graph](https://developers.arcgis.com/javascript/latest/sample-code/knowledgegraph-search/)
 * @see [GraphQueryStreamingResult](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-knowledgeGraph-GraphQueryStreamingResult.html)
 * @see [executeSearchStreaming()](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-knowledgeGraphService.html#executeSearchStreaming)
 * @example
 * // example GraphSearchStreaming used in a executeSearchStreaming
 * KnowledgeGraphModule.executeSearchStreaming(
 *   knowledgeGraph,
 *   { // autocasts to new GraphSearchStreaming
 *     searchQuery: "solar",
 *     typeCategoryFilter: "both",
 *     returnSearchContext: false,
 *     start: 1, // index of first record to return
 *     num: 200, // return 200 records.
 *     namedTypesFilter: ["Company", "Supplier", "Part"],
 *     idsFilter: ["{G4E8G2S8D-2GS5-98S4-3S5D-S1DE7G45DS48}",
 *                      "{FNWI1G5W-1A5W-3A5W-8412-A1W5F4W8F7AS}",
 *                      "{9D2D6AFD-41F1-49A4-8412-CACCC9906E88}"]
 *   }
 * ).then((streamingSearchResult)=>{
 *   // the result of a streaming search is a readableStream which requires decoding.
 *   readStream(streamingSearchResult)
 * })
 * @example
 * // a function to read the readable stream returned from the above query
 * const readStream = async (streamingQueryResult) => {
 *   let time = Date.now();
 *   let reader = streamingQueryResult.resultRowsStream.getReader();
 *   try {
 *     while (true) {
 *       const { done, value } = await reader.read();
 *       if (done) {
 *         console.log(`Completed database requests: ${(Date.now() - time) / 1000} seconds`, value);
 *         break;
 *       }
 *       console.log(`Chunk returned in: ${(Date.now() - time) / 1000} seconds`, value)
 *     }
 *   } catch (err) {
 *     if (err.name === "AbortError") {
 *       console.log("Request aborted as expected");
 *     } else {
 *       throw err;
 *     }
 *   }
 * };
 * @example
 * // sample result of read streaming search result chunk printed to the console
 * "Streaming chunk returned in: 0.082 seconds"
 * [
 *   [{
 *     "declaredClass": "esri.rest.knowledgeGraph.Entity",
 *     "properties": {
 *       "Name": "Suncommon",
 *       "Employee_Count": 400,
 *       "energyType": "solar"
 *     },
 *     "typeName": "Company",
 *     "id": "{G4E8G2S8D-2GS5-98S4-3S5D-S1DE7G45DS48}"
 *   }],
 *   [{
 *     "declaredClass": "esri.rest.knowledgeGraph.Entity",
 *     "properties": {
 *       "Name": "Quality Solar Supply",
 *       "Supplier_code": "158B",
 *       "City": "New Orleans",
 *     },
 *     "typeName": "Supplier",
 *     "id": "{FNWI1G5W-1A5W-3A5W-8412-A1W5F4W8F7AS}"
 *   }],
 *   [{
 *     "declaredClass": "esri.rest.knowledgeGraph.Entity",
 *     "properties": {
 *       "Name": "Solar panel",
 *       "panel_type": "Polycrystalline",
 *       "price_per_unit": 400
 *     },
 *     "typeName": "Part",
 *     "id": "{9D2D6AFD-41F1-49A4-8412-CACCC9906E88}"
 *   }]
 * ]
 */
export default class GraphSearchStreaming extends GraphSearch {
  constructor(properties?: GraphSearchStreamingProperties);
  /** Specifies list of IDs to search. */
  accessor idsFilter: string[] | null | undefined;
  /**
   * Specifies list of names of [entity types](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-knowledgeGraph-EntityType.html#name) or [relationship types](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-knowledgeGraph-RelationshipType.html#name) to search.
   * Note that if the `typeCategoryFilter` property is set to `provenance`, the search is restricted to the provenance meta entity type; entering any values other than the provenance meta entity type name will result in an error.
   */
  accessor namedTypesFilter: string[] | null | undefined;
  /** The maximum number of results returned from the search. */
  accessor num: number | null | undefined;
  /**
   * If `true`, returns the IDs of objects that match the search, the names of the properties that matched the search term, scores and highlights of the result set.
   *
   * @default false
   */
  accessor returnSearchContext: boolean;
  /** The index of the first result to return. */
  accessor start: number | null | undefined;
}