import { LoadingState } from '@grafana/data';
import { Observable } from '../node_modules/rxjs/dist/esm5/internal/Observable.js';

const DELAY_INTERVAL_MS = 10;
const MAX_NEXT_REQUEST_DELAY = 1e4 / DELAY_INTERVAL_MS;
function getRequestLooper(req, options) {
  return new Observable((subscriber) => {
    let nextQuery = undefined;
    let subscription = undefined;
    let loadingState = LoadingState.Loading;
    let nextRequestDelay = 1;
    let count = 1;
    let shouldCancel = false;
    const observer = {
      next: (rsp) => {
        loadingState = rsp.state;
        let checkstate = false;
        if (loadingState !== LoadingState.Error) {
          nextQuery = options.getNextQuery(rsp);
          const _shouldCancel = options.shouldCancel();
          if (nextQuery && _shouldCancel) {
            shouldCancel = _shouldCancel;
            nextQuery = undefined;
          }
          checkstate = true;
        }
        const data = options.process(rsp.data);
        if (checkstate) {
          if (nextQuery) {
            if (data.length && data[0].length) {
              loadingState = LoadingState.Streaming;
            } else {
              loadingState = LoadingState.Loading;
            }
            nextRequestDelay = nextRequestDelay * 2 > MAX_NEXT_REQUEST_DELAY ? MAX_NEXT_REQUEST_DELAY : nextRequestDelay * 2;
          } else {
            loadingState = LoadingState.Done;
            nextRequestDelay = 0;
          }
        }
        subscriber.next({ ...rsp, data, state: loadingState, key: req.requestId });
      },
      error: (err) => {
        subscriber.error(err);
      },
      complete: () => {
        if (subscription) {
          subscription.unsubscribe();
          subscription = undefined;
        }
        if (nextQuery) {
          const next = nextQuery;
          setTimeout(() => {
            subscription = options.query({ ...req, requestId: `${req.requestId}.${++count}`, targets: [next] }).subscribe(observer);
            nextQuery = undefined;
          }, nextRequestDelay * DELAY_INTERVAL_MS);
        } else {
          subscriber.complete();
        }
      }
    };
    subscription = options.query(req).subscribe(observer);
    return function unsubscribe() {
      observer.complete();
      if (nextQuery || shouldCancel) {
        options.onCancel();
      }
      nextQuery = undefined;
    };
  });
}

export { getRequestLooper };
//# sourceMappingURL=requestLooper.js.map
