import { ApiFn } from './types';
import { resourceCache } from './cache';
import { initializeDataReader } from './dataReaderInitializer';


/**
 *
 * @param apiFn A typical api function that doesn't take any parameters.
 */
export function updateCache<ResponseType>(
  apiFn: ApiFn<ResponseType>,
): Promise<void>;

/**
 *
 * @param apiFn A typical api function with parameters.
 * @param parameters An arbitrary number of parameters.
 */
export function updateCache<ResponseType, ArgTypes extends unknown[]>(
  apiFn: ApiFn<ResponseType, ArgTypes>,
  ...parameters: ArgTypes
): Promise<void>;


/**
 *
 * @param apiFn A typical api function with parameters.
 * @param parameters An arbitrary number of parameters.
 */
export function updateCache<ResponseType, ArgTypes extends unknown[] = []>(
  apiFn: ApiFn<ResponseType, ArgTypes>,
  ...parameters: ArgTypes
) {
  // clear any previously set cache
  resourceCache(apiFn).delete(...parameters);

  // re-initialize the data reader, caching it
  const updateResource = initializeDataReader(apiFn, ...parameters);

  try {
    // immediately call the data reader so we can access the api request
    // this should always throw a Promise
    updateResource();
  } catch (p) {
    /* istanbul ignore else */
    if ('then' in p) {
      // return the ongoing api request
      return p as Promise<ResponseType>;
    }
  }

  // this should never happen
  /* istanbul ignore next */
  throw Error(`Cannot update cache for ${apiFn.name}`);
}
