class InterceptorHandlerResponse {
  constructor(value, error, visible) {
    this.value = value;
    this.error = error;
    this.visible = visible;
  }
}

const interceptorTypeMap = new Map();
/**
 * Saves the interceptor into the interceptorTypeMap.
 * @param interceptorType is the identifier of the interceptor.
 * @param generator function that is expected to generate the interceptor with the given config.
 */
function registerInterceptor(interceptorType, generator) {
  interceptorTypeMap.set(interceptorType, generator);
}
/**
 * Generates an interceptor handler with the given config.
 *
 * @param config that contains all the parameters that the interceptor needs.
 */
function generateInterceptor(config) {
  const generator = interceptorTypeMap.get(config.id);
  if (generator) {
    return generator(config);
  }
  return undefined;
}
/**
 * Executes the given interceptors in order. Passes the response of each interceptor's result to the next
 * interceptor. Returns error of the first failed interceptor or returns the result of the last interceptor
 * if none returns an error.
 *
 * @param context of the form.
 * @param values of the fields in the form.
 * @param field that is being executed.
 * @param value that the interceptor will process.
 * @param visibility of the current field.
 * @param interceptorBundle that contains interceptor list for each type.
 * @param interceptorType that is expected to be used.
 * @param boundField is the field that the interceptor is bound to. Used only for 'onFormChange' interceptor types.
 */
function executeInterceptors(context, values, field, value, visibility, interceptorBundle, interceptorType, boundField) {
  const interceptors = interceptorBundle ? (interceptorBundle[interceptorType] || []) : [];
  let v = boundField ? values[boundField.id] : value;
  let visible = visibility;
  for (const interceptor of interceptors) {
    if (!interceptor) {
      continue;
    }
    const response = interceptor.run(context, values, field, v, boundField);
    if (typeof response.visible === 'boolean') {
      visible = response.visible;
    }
    if (response.error) {
      // don't proceed to next interceptor if an error returned
      return response;
    }
    v = response.value;
  }
  return new InterceptorHandlerResponse(v, undefined, visible);
}

class InterceptorConfig {
  constructor(id) {
    this.id = id;
  }
}

class InterceptorHandler {
}

export { InterceptorConfig as I, InterceptorHandler as a, executeInterceptors as e, generateInterceptor as g, registerInterceptor as r };
