// 4.1. Extensions to ServiceWorkerGlobalScope

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

// 4.2. Extensions to ServiceWorkerRegistration

partial interface ServiceWorkerRegistration {
  readonly attribute BackgroundFetchManager backgroundFetch;
};

// 4.3. BackgroundFetchManager

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

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

// 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;
};

// 4.4. BackgroundFetchRegistration

[Exposed=(Window,Worker)]
interface BackgroundFetchRegistration : EventTarget {
  readonly attribute DOMString id;
  readonly attribute unsigned long long uploadTotal;
  readonly attribute unsigned long long uploaded;
  readonly attribute unsigned long long downloadTotal;
  readonly attribute unsigned long long downloaded;
  readonly attribute BackgroundFetchActiveFetches activeFetches;

  attribute EventHandler onprogress;

  Promise<boolean> abort();
};

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

[Exposed=(Window,Worker)]
interface BackgroundFetchActiveFetches {
  Promise<BackgroundFetchActiveFetch> match(RequestInfo request);
  Promise<FrozenArray<BackgroundFetchActiveFetch>> values();
};

[Exposed=(Window,Worker)]
interface BackgroundFetchActiveFetch : BackgroundFetchFetch {
  readonly attribute Promise<Response> responseReady;
  // In future this will include a fetch observer
};

// 4.4.3. BackgroundFetchEvent

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

dictionary BackgroundFetchEventInit : ExtendableEventInit {
  required DOMString id;
};

// 4.4.4. BackgroundFetchSettledEvent

[Constructor(DOMString type, BackgroundFetchSettledEventInit init), Exposed=ServiceWorker]
interface BackgroundFetchSettledEvent : BackgroundFetchEvent {
  readonly attribute BackgroundFetchSettledFetches fetches;
};

dictionary BackgroundFetchSettledEventInit : BackgroundFetchEventInit {
  required BackgroundFetchSettledFetches fetches;
};

[Exposed=ServiceWorker]
interface BackgroundFetchSettledFetches {
  Promise<BackgroundFetchSettledFetch> match(RequestInfo request);
  Promise<FrozenArray<BackgroundFetchSettledFetch>> values();
};

[Exposed=ServiceWorker]
interface BackgroundFetchSettledFetch : BackgroundFetchFetch {
  readonly attribute Response? response;
};

// 4.4.5. BackgroundFetchUpdateEvent

[Constructor(DOMString type, BackgroundFetchSettledEventInit init), Exposed=ServiceWorker]
interface BackgroundFetchUpdateEvent : BackgroundFetchSettledEvent {
  Promise<void> updateUI(DOMString title);
};

// 4.4.6. BackgroundFetchClickEvent

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

dictionary BackgroundFetchClickEventInit : BackgroundFetchEventInit {
  required BackgroundFetchState state;
};

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