import { ITrigger, ITriggerRedirect } from './Trigger';

/**
 * Describes the plan of execution of a search request.
 */
export interface IPlanResponse {
  /**
   * The output that would be included by the Search API in the query response
   * once the search request has been fully processed by the query pipeline.
   */
  preprocessingOutput: {
    /**
     * The query response output generated by _trigger_ rules in the query
     * pipeline (i.e., by `execute`, `notify`, `query`, and `redirect` rules).
     */
    triggers: ITrigger<any>[];
  };
  /**
   * The query expressions that would be sent to the index once the search
   * request has been fully processed by the query pipeline.
   */
  parsedInput: {
    /**
     * The final basic query expression (`q`).
     */
    basicExpression: string;
    /**
     * The final large query expression (`lq`).
     */
    largeExpression: string;
  };
}

/**
 * The plan of execution of a search request.
 */
export class ExecutionPlan {
  constructor(private response: IPlanResponse) {}

  /**
   * Gets the final value of the basic expression (`q`) after the search request has been processed in the query pipeline, but before it is sent to the index.
   */
  public get basicExpression() {
    return this.response.parsedInput.basicExpression;
  }

  /**
   * Gets the final value of the large expression (`lq`) after the search request has been processed in the query pipeline, but before it is sent to the index.
   */
  public get largeExpression() {
    return this.response.parsedInput.largeExpression;
  }

  /**
   * Gets the URL to redirect the browser to, if the search request satisfies the condition of a `redirect` trigger rule in the query pipeline.
   *
   * Returns `null` otherwise.
   */
  public get redirectionURL() {
    const redirects: ITriggerRedirect[] = this.response.preprocessingOutput.triggers.filter(trigger => trigger.type === 'redirect');
    return redirects.length ? redirects[0].content : null;
  }
}
