package org.robolectric.shadows;

import android.app.Notification;
import android.app.NotificationManager;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Shadow for {@link android.app.NotificationManager}.
 */
@SuppressWarnings({"UnusedDeclaration"})
@Implements(NotificationManager.class)
public class ShadowNotificationManager {
  private Map<Key, Notification> notifications = new HashMap<>();

  @Implementation
  public void notify(int id, Notification notification) {
    notify(null, id, notification);
  }

  @Implementation
  public void notify(String tag, int id, Notification notification) {
    notifications.put(new Key(tag, id), notification);
  }

  @Implementation
  public void cancel(int id) {
    cancel(null, id);
  }

  @Implementation
  public void cancel(String tag, int id) {
    Key key = new Key(tag, id);
    if (notifications.containsKey(key)) {
      notifications.remove(key);
    }
  }

  @Implementation
  public void cancelAll() {
    notifications.clear();
  }

  public int size() {
    return notifications.size();
  }

  public Notification getNotification(int id) {
    return notifications.get(new Key(null, id));
  }

  public Notification getNotification(String tag, int id) {
    return notifications.get(new Key(tag, id));
  }

  public List<Notification> getAllNotifications() {
    return new ArrayList<>(notifications.values());
  }

  private static final class Key {
    public final String tag;
    public final int id;

    private Key(String tag, int id) {
      this.tag = tag;
      this.id = id;
    }

    @Override
    public int hashCode() {
      int hashCode = 17;
      hashCode = 37 * hashCode + (tag == null ? 0 : tag.hashCode());
      hashCode = 37 * hashCode + id;
      return hashCode;
    }

    @Override
    public boolean equals(Object o) {
      if (!(o instanceof Key)) return false;
      Key other = (Key) o;
      return (this.tag == null ? other.tag == null : this.tag.equals(other.tag)) && this.id == other.id;
    }
  }
}

@@ -100,16 +100,75 @@
 anager;%0A
+import android.service.notification.StatusBarNotification;%0A
 import o
@@ -254,16 +254,59 @@
 lements;
+%0Aimport org.robolectric.RuntimeEnvironment;
 %0A%0Aimport
@@ -1240,32 +1240,724 @@
 s.clear();%0A  %7D%0A%0A
+  @Implementation%0A  public StatusBarNotification%5B%5D getActiveNotifications() %7B%0A    StatusBarNotification%5B%5D statusBarNotifications =%0A        new StatusBarNotification%5Bnotifications.size()%5D;%0A    int i = 0;%0A    for (Map.Entry%3CKey, Notification%3E entry : notifications.entrySet()) %7B%0A      statusBarNotifications%5Bi++%5D = new StatusBarNotification(%0A%09  RuntimeEnvironment.application.getPackageName(),%0A%09  null /* opPkg */,%0A%09  entry.getKey().id,%0A%09  entry.getKey().tag,%0A%09  android.os.Process.myUid() /* uid */,%0A%09  android.os.Process.myPid() /* initialPid */,%0A%09  0 /* score */,%0A%09  entry.getValue(),%0A%09  android.os.Process.myUserHandle(),%0A%09  0 /* postTime */);%0A    %7D%0A    return statusBarNotifications;%0A  %7D%0A%0A
   public int siz

Add shadow for NotificationManager#getActiveNotifications().