/**
 * This file is part of the Meeds project (https://meeds.io/).
 *
 * Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package org.exoplatform.commons.notification.storage;

import java.util.Calendar;
import java.util.List;

import org.exoplatform.commons.api.notification.model.NotificationInfo;
import org.exoplatform.commons.api.notification.model.WebNotificationFilter;
import org.exoplatform.commons.notification.BaseNotificationTestCase;
import org.exoplatform.commons.notification.plugin.PluginTest;

public class WebNotificationStorageTest extends BaseNotificationTestCase {

  public void testSaveWebNotification() throws Exception {
    String userId = "root1";
    userIds.add(userId);
    NotificationInfo info = makeWebNotificationInfo(userId);
    storage.save(info);
    //
    assertEquals(1, storage.get(new WebNotificationFilter(userId), 0, 10).size());
  }

  public void testMarkRead() throws Exception {
    String userId = "root2";
    userIds.add(userId);
    NotificationInfo info = makeWebNotificationInfo(userId);
    storage.save(info);
    List<NotificationInfo> list = storage.get(new WebNotificationFilter(userId), 0, 10);
    assertEquals(1, list.size());
    NotificationInfo notif = list.get(0);
    assertFalse(notif.isRead());
    //
    storage.markRead(notif.getId());
    //
    notif = storage.get(notif.getId());
    assertTrue(notif.isRead());
  }

  public void testMarkReadAll() throws Exception {
    String userId = "demo18";
    userIds.add(userId);
    for (int i = 0; i < 10; i++) {
      NotificationInfo info = makeWebNotificationInfo(userId);
      storage.save(info);
    }
    List<NotificationInfo> list = storage.get(new WebNotificationFilter(userId), 0, 10);
    assertEquals(10, list.size());
    for(NotificationInfo notif : list) {
      assertFalse(notif.isRead());
    }
    //
    storage.markAllRead(userId);
    restartTransaction();
    //
    list = storage.get(new WebNotificationFilter(userId), 0, 10);
    assertEquals(10, list.size());
    //
    for(NotificationInfo notif : list) {
      assertTrue(notif.isRead());
    }
  }
  
  public void testUpdateNotification() throws Exception {
    String userId = "john5";
    NotificationInfo info = makeWebNotificationInfo(userId);
    storage.save(info);
    String notifId = info.getId();
    NotificationInfo got = storage.get(notifId);
    assertNotNull(got);
    assertEquals("The title", got.getTitle());
    long lastUpdatedTime = got.getLastModifiedDate();
    
    //update and move top, the lastUpdatedTime will be modified
    got = makeWebNotificationInfo(userId);
    got.setId(notifId);
    got.setTitle("new title");
    // wait 1 millisecond to not have same updated timestamp
    Thread.sleep(1);
    storage.update(got, true);
    restartTransaction();

    got = storage.get(got.getId());
    assertEquals("new title", got.getTitle());
    assertFalse(got.getLastModifiedDate() + " should have been modified and not equal anymore to " + lastUpdatedTime, lastUpdatedTime == got.getLastModifiedDate());
    
    //update but don't move top, the lastUpdatedTime will not be modified
    lastUpdatedTime = got.getLastModifiedDate();
    got.setTitle("new new title");
    storage.update(got, false);
    restartTransaction();
    got = storage.get(notifId);
    assertEquals("new new title", got.getTitle());
    assertTrue(got.getLastModifiedDate() + " should be equal to " + lastUpdatedTime, lastUpdatedTime == got.getLastModifiedDate());
  }

  public void testGetNewMessage() throws Exception  {
    //
    String userId = "root16";
    userIds.add(userId);
    storage.save(makeWebNotificationInfo(userId));
    //
    assertEquals(1, storage.getNumberOnBadge(userId));
    storage.save(makeWebNotificationInfo(userId));
    assertEquals(2, storage.getNumberOnBadge(userId));
    for (int i = 0; i < 10; ++i) {
      storage.save(makeWebNotificationInfo(userId));
    }
    //
    List<NotificationInfo> list = storage.get(new WebNotificationFilter(userId), 0, 15);
    assertEquals(12, list.size());
    //
    assertEquals(12, storage.getNumberOnBadge(userId));
    //
    storage.resetNumberOnBadge(userId);
    //
    assertEquals(0, storage.getNumberOnBadge(userId));
  }
  
  public void testSpecialUserNameToGetMessage() throws Exception {
    //Test with methods: getUnreadNotification, getNewMessage and remove
    String userId = "don't_blink_polarity";
    userIds.add(userId);
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(cal.getTimeInMillis() - 3 * 86400000l);
    //
    NotificationInfo notification = makeWebNotificationInfo(userId);
    notification.setDateCreated(cal);
    notification.setLastModifiedDate(cal);
    storage.save(notification);
    assertEquals(PluginTest.ID, storage.getUnreadNotification(PluginTest.ID, "TheActivityId", userId).getKey().getId());
    assertEquals(1, storage.getNumberOnBadge(userId));
    assertTrue(storage.remove(userId, 2 * 86400));
    //
    assertEquals(0, storage.getNumberOnBadge(userId));
  }

}