package com.madgnome.jira.plugins.jirachievements.data.services.impl;

import com.atlassian.activeobjects.external.ActiveObjects;
import com.madgnome.jira.plugins.jirachievements.data.ao.*;
import com.madgnome.jira.plugins.jirachievements.data.services.IAchievementDaoService;

import java.util.*;

public class AchievementDaoService extends ReferencableDaoService<Achievement, AchievementRefEnum> implements IAchievementDaoService
{
  @Override
  protected Class<Achievement> getClazz()
  {
    return Achievement.class;
  }

  public AchievementDaoService(ActiveObjects ao)
  {
    super(ao);
  }

  public List<Achievement> allActive()
  {
    return Arrays.asList(ao.find(getClazz(), "ACTIVE = ?", true));
  }

  public Map<Category, List<Achievement>> allGroupByCategory()
  {
    Map<Category, List<Achievement>> achievementByCategory = new HashMap<Category, List<Achievement>>();
    List<Achievement> achievements = all();
    for (Achievement achievement : achievements)
    {
      Category category = achievement.getCategory();
      List<Achievement> categoryAchievements = achievementByCategory.get(category);
      if (categoryAchievements == null)
      {
        categoryAchievements = new ArrayList<Achievement>();
        achievementByCategory.put(category, categoryAchievements);
      }

      categoryAchievements.add(achievement);
    }
    
    return achievementByCategory;
  }

  public Map<String, List<Achievement>> allGroupByCategoryName()
  {
    Map<String, List<Achievement>> achievementByCategory = new HashMap<String, List<Achievement>>();
    List<Achievement> achievements = all();
    for (Achievement achievement : achievements)
    {
      Category category = achievement.getCategory();
      List<Achievement> categoryAchievements = achievementByCategory.get(category.toString());
      if (categoryAchievements == null)
      {
        categoryAchievements = new ArrayList<Achievement>();
        achievementByCategory.put(category.toString(), categoryAchievements);
      }

      categoryAchievements.add(achievement);
    }

    return achievementByCategory;
  }

  public void activate(int id, boolean activate)
  {
    Achievement achievement = get(id);
    if (achievement == null)
    {
      logger.warn("No achievement found with this id: ", id);
      return;
    }

    achievement.setActive(activate);
    achievement.save();
  }

  public List<Achievement> getUserNewAchievements(UserWrapper userWrapper)
  {
    // TODO: use Query with join when join will be fixed in AO with postgresql
//    Query query = Query.select().join(UserAchievement.class, AOUtil.getTablePrefix() + "_ACHIEVEMENT.ID = ACHIEVEMENT_ID")
//                                .where("USER_WRAPPER_ID = ? AND NOTIFIED = ?", userWrapper.getID(), false);

    List<Achievement> achievements = new ArrayList<Achievement>();
    UserAchievement[] userAchievements = ao.find(UserAchievement.class, "USER_WRAPPER_ID = ? AND NOTIFIED = ?", userWrapper.getID(), false);
    for (UserAchievement userAchievement : userAchievements)
    {
      achievements.add(userAchievement.getAchievement());
    }

    return achievements;
  }
}

@@ -269,16 +269,42 @@
 Service;
+%0Aimport net.java.ao.Query;
 %0A%0Aimport
@@ -2489,434 +2489,178 @@
     
-// TODO: use Query with join when join will be fixed in AO with postgresql%0A//    Query query = Query.select().join(UserAchievement.class, AOUtil.getTablePrefix() + %22_ACHIEVEMENT.ID = ACHIEVEMENT_ID%22)%0A//                                .where(%22USER_WRAPPER_ID = ? AND NOTIFIED = ?%22, userWrapper.getID(), false);%0A%0A    List%3CAchievement%3E achievements = new ArrayList%3CAchievement%3E();%0A    UserAchievement%5B%5D userAchievements = ao.f
+Query query = Query.select()%0A                       .alias(UserAchievement.class, %22ua%22)%0A                       .alias(Achievement.class, %22a%22)%0A                       .jo
 in
-d
 (Use
@@ -2678,17 +2678,74 @@
 t.class,
- 
+%22ua.ACHIEVEMENT_ID = a.ID%22)%0A                       .where(
 %22USER_WR
@@ -2809,163 +2809,68 @@
 e);%0A
+%0A
     
-for (UserAchievement userAchievement : userAchievements)%0A    %7B%0A      achievements.add(userAchievement.getAchievement());%0A    %7D%0A%0A    return achievements
+return Arrays.asList(ao.find(Achievement.class, query))
 ;%0A  

Switch back to using a join in getUserNewAchievements request