// 3.1. Extensions to ServiceWorkerRegistration

partial interface ServiceWorkerRegistration {
  readonly attribute BackgroundFetchManager backgroundFetch;
};

// 3.2. BackgroundFetchManager

[Exposed=(Window,Worker)]
interface BackgroundFetchManager {
  Promise<BackgroundFetchRegistration> fetch(DOMString tag, (RequestInfo or sequence<RequestInfo>) requests, optional BackgroundFetchOptions options);
  Promise<BackgroundFetchRegistration?> get(DOMString tag);
  Promise<FrozenArray<DOMString>> getTags();
  // TODO: in future this should become an async iterator for BackgroundFetchRegistration objects
};

dictionary BackgroundFetchOptions {
  sequence<IconDefinition> icons;
  DOMString title;
  long totalDownloadSize;
};

// This is taken from https://w3c.github.io/manifest/#icons-member.
// This definition should probably be moved somewhere more general.
dictionary IconDefinition {
  DOMString src;
  DOMString sizes;
  DOMString type;
};

// 3.3. BackgroundFetchRegistration

[Exposed=(Window,Worker)]
interface BackgroundFetchRegistration {
  readonly attribute DOMString tag;
  readonly attribute FrozenArray<IconDefinition> icons;
  readonly attribute long totalDownloadSize;
  readonly attribute DOMString title;
  readonly attribute FrozenArray<BackgroundFetchActiveFetches> fetches;

  void abort();
};

[Exposed=(Window,Worker)]
interface BackgroundFetchFetches {
  readonly attribute Request request;
};

[Exposed=(Window,Worker)]
interface BackgroundFetchActiveFetches : BackgroundFetchFetches {
  readonly attribute Promise<Response> responseReady;
  // TODO: this will include fetch controller/observer objects
};

// 3.4. Events

partial interface ServiceWorkerGlobalScope {
  attribute EventHandler onbackgroundfetched;
  attribute EventHandler onbackgroundfetchfail;
  attribute EventHandler onbackgroundfetchabort;
  attribute EventHandler onbackgroundfetchclick;
};

// 3.4.1. BackgroundFetchEvent

[Constructor(DOMString type, BackgroundFetchEventInit init), Exposed=ServiceWorker]
interface BackgroundFetchEvent : ExtendableEvent {
  readonly attribute DOMString tag;
};

dictionary BackgroundFetchEventInit : ExtendableEventInit {
  required DOMString tag;
};

// 3.4.2. BackgroundFetchEndEvent

[Constructor(DOMString type, BackgroundFetchEndEventInit init), Exposed=ServiceWorker]
interface BackgroundFetchEndEvent : BackgroundFetchEvent {
  readonly attribute FrozenArray<BackgroundFetchSettledFetches> completeFetches;

  Promise<void> updateUI(DOMString title);
};

dictionary BackgroundFetchEndEventInit : BackgroundFetchEventInit {
  required BackgroundFetchSettledFetches completeFetches;
};

[Exposed=ServiceWorker]
interface BackgroundFetchSettledFetches : BackgroundFetchFetches {
  readonly attribute Response? response;
};

// 3.4.3. BackgroundFetchFailEvent

[Constructor(DOMString type, BackgroundFetchEndEventInit init), Exposed=ServiceWorker]
interface BackgroundFetchFailEvent : BackgroundFetchEndEvent {
  readonly attribute FrozenArray<BackgroundFetchSettledFetches> failedFetches;
};

dictionary BackgroundFetchFailEventInit : BackgroundFetchEndEventInit {
  required BackgroundFetchSettledFetches failedFetches;
};

// 3.4.4. BackgroundFetchClickEvent

[Constructor(DOMString type, BackgroundFetchEndEventInit init), Exposed=ServiceWorker]
interface BackgroundFetchClickEvent : BackgroundFetchEvent {
  readonly attribute BackgroundFetchState state;
};

dictionary BackgroundFetchClickEventInit : BackgroundFetchEventInit {
  required BackgroundFetchState state;
};

enum BackgroundFetchState { "pending", "succeeded", "failed" };
