/**
   * Append the calendars of a list of groups. The groups must have their calendar tool enabled,
   * this routine doesn't check it.
   *
   * @param ureq
   * @param groups
   * @param isOwner
   * @param calendars
   */
  private void addCalendars(
      List<BusinessGroup> groups,
      boolean isOwner,
      boolean isParticipant,
      List<KalendarRenderWrapper> calendars,
      Map<CalendarKey, CalendarUserConfiguration> configMap) {

    Map<Long, Long> groupKeyToAccess =
        CoreSpringFactory.getImpl(CollaborationManager.class).lookupCalendarAccess(groups);
    for (BusinessGroup bGroup : groups) {
      KalendarRenderWrapper groupCalendarWrapper = calendarManager.getGroupCalendar(bGroup);
      groupCalendarWrapper.setPrivateEventsVisible(true);
      // set calendar access
      int iCalAccess = CollaborationTools.CALENDAR_ACCESS_OWNERS;
      Long lCalAccess = groupKeyToAccess.get(bGroup.getKey());
      if (lCalAccess != null) {
        iCalAccess = lCalAccess.intValue();
      }
      if (iCalAccess == CollaborationTools.CALENDAR_ACCESS_OWNERS && !isOwner) {
        groupCalendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_ONLY);
      } else {
        groupCalendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_WRITE);
      }
      CalendarUserConfiguration config = configMap.get(groupCalendarWrapper.getCalendarKey());
      if (config != null) {
        groupCalendarWrapper.setConfiguration(config);
      }
      if (isOwner || isParticipant) {
        groupCalendarWrapper.setPrivateEventsVisible(true);
      }
      calendars.add(groupCalendarWrapper);
    }
  }
  @Override
  public List<KalendarRenderWrapper> getListOfCalendarWrappers(
      UserRequest ureq, WindowControl wControl) {
    if (!calendarModule.isEnabled()) {
      return new ArrayList<KalendarRenderWrapper>();
    }

    Identity identity = ureq.getIdentity();

    List<KalendarRenderWrapper> calendars = new ArrayList<KalendarRenderWrapper>();
    Map<CalendarKey, CalendarUserConfiguration> configMap =
        calendarManager.getCalendarUserConfigurationsMap(ureq.getIdentity());
    appendPersonalCalendar(identity, calendars, configMap);
    appendGroupCalendars(identity, calendars, configMap);
    appendCourseCalendars(ureq, wControl, calendars, configMap);

    // reload every hour
    List<KalendarRenderWrapper> importedCalendars =
        importCalendarManager.getImportedCalendarsForIdentity(identity, true);
    for (KalendarRenderWrapper importedCalendar : importedCalendars) {
      importedCalendar.setPrivateEventsVisible(true);
    }

    calendars.addAll(importedCalendars);
    return calendars;
  }
 private void appendPersonalCalendar(
     Identity identity,
     List<KalendarRenderWrapper> calendars,
     Map<CalendarKey, CalendarUserConfiguration> configMap) {
   // get the personal calendar
   if (calendarModule.isEnablePersonalCalendar()) {
     KalendarRenderWrapper calendarWrapper = calendarManager.getPersonalCalendar(identity);
     calendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_WRITE);
     calendarWrapper.setPrivateEventsVisible(true);
     CalendarUserConfiguration config = configMap.get(calendarWrapper.getCalendarKey());
     if (config != null) {
       calendarWrapper.setConfiguration(config);
     }
     calendars.add(calendarWrapper);
   }
 }
  @Override
  public List<CalendarFileInfos> getListOfCalendarsFiles(Identity identity) {
    List<CalendarFileInfos> aggregatedFiles = new ArrayList<>();

    Map<CalendarKey, CalendarUserConfiguration> configMap =
        calendarManager.getCalendarUserConfigurationsMap(identity);

    // personal calendar
    CalendarKey personalCalendarKey =
        new CalendarKey(identity.getName(), CalendarManager.TYPE_USER);
    CalendarUserConfiguration personalCalendarConfig = configMap.get(personalCalendarKey);
    if (calendarModule.isEnablePersonalCalendar()
        && (personalCalendarConfig == null || personalCalendarConfig.isInAggregatedFeed())) {
      File iCalFile =
          calendarManager.getCalendarICalFile(CalendarManager.TYPE_USER, identity.getName());
      if (iCalFile != null) {
        aggregatedFiles.add(
            new CalendarFileInfos(identity.getName(), CalendarManager.TYPE_USER, iCalFile));
      }

      // reload every hour
      List<CalendarFileInfos> importedCalendars =
          importCalendarManager.getImportedCalendarInfosForIdentity(identity, true);
      aggregatedFiles.addAll(importedCalendars);
    }

    // group calendars
    if (calendarModule.isEnableGroupCalendar()) {
      SearchBusinessGroupParams groupParams = new SearchBusinessGroupParams(identity, true, true);
      groupParams.addTools(CollaborationTools.TOOL_CALENDAR);
      List<BusinessGroup> groups =
          businessGroupService.findBusinessGroups(groupParams, null, 0, -1);
      for (BusinessGroup group : groups) {
        String calendarId = group.getKey().toString();
        CalendarKey key = new CalendarKey(calendarId, CalendarManager.TYPE_GROUP);
        CalendarUserConfiguration calendarConfig = configMap.get(key);
        if (calendarConfig == null || calendarConfig.isInAggregatedFeed()) {
          File iCalFile =
              calendarManager.getCalendarICalFile(CalendarManager.TYPE_GROUP, calendarId);
          if (iCalFile != null) {
            aggregatedFiles.add(
                new CalendarFileInfos(calendarId, CalendarManager.TYPE_GROUP, iCalFile));
          }
        }
      }
    }

    if (calendarModule.isEnableCourseElementCalendar()
        || calendarModule.isEnableCourseToolCalendar()) {
      List<Object[]> resources = getCourses(identity);
      for (Object[] resource : resources) {
        RepositoryEntry courseEntry = (RepositoryEntry) resource[0];
        String calendarId = courseEntry.getOlatResource().getResourceableId().toString();
        CalendarKey key = new CalendarKey(calendarId, CalendarManager.TYPE_COURSE);
        CalendarUserConfiguration calendarConfig = configMap.get(key);
        if (calendarConfig == null || calendarConfig.isInAggregatedFeed()) {
          File iCalFile =
              calendarManager.getCalendarICalFile(CalendarManager.TYPE_COURSE, calendarId);
          if (iCalFile != null) {
            aggregatedFiles.add(
                new CalendarFileInfos(calendarId, CalendarManager.TYPE_COURSE, iCalFile));
          }
        }
      }
    }

    return aggregatedFiles;
  }
  private void appendCourseCalendars(
      UserRequest ureq,
      WindowControl wControl,
      List<KalendarRenderWrapper> calendars,
      Map<CalendarKey, CalendarUserConfiguration> configMap) {
    if (calendarModule.isEnableCourseElementCalendar()
        || calendarModule.isEnableCourseToolCalendar()) {

      // add course calendars
      List<Object[]> resources = getCourses(ureq.getIdentity());
      Set<OLATResource> editoredResources = getEditorGrants(ureq.getIdentity());

      Set<Long> duplicates = new HashSet<>();

      for (Object[] resource : resources) {
        RepositoryEntry courseEntry = (RepositoryEntry) resource[0];
        if (duplicates.contains(courseEntry.getKey())) {
          continue;
        }
        duplicates.add(courseEntry.getKey());

        String role = (String) resource[1];
        Long courseResourceableID = courseEntry.getOlatResource().getResourceableId();
        try {
          ICourse course = CourseFactory.loadCourse(courseEntry);
          if (isCourseCalendarEnabled(course)) {
            // calendar course aren't enabled per default but course node of type calendar are
            // always possible
            // REVIEW if (!course.getCourseEnvironment().getCourseConfig().isCalendarEnabled())
            // continue;
            // add course calendar
            KalendarRenderWrapper courseCalendarWrapper = calendarManager.getCourseCalendar(course);
            boolean isPrivileged =
                GroupRoles.owner.name().equals(role)
                    || editoredResources.contains(courseEntry.getOlatResource());
            if (isPrivileged) {
              courseCalendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_WRITE);
            } else {
              courseCalendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_ONLY);
            }

            if (role != null
                && (GroupRoles.owner.name().equals(role)
                    || GroupRoles.coach.name().equals(role)
                    || GroupRoles.participant.name().equals(role))) {
              courseCalendarWrapper.setPrivateEventsVisible(true);
            }

            CalendarUserConfiguration config =
                configMap.get(courseCalendarWrapper.getCalendarKey());
            if (config != null) {
              courseCalendarWrapper.setConfiguration(config);
            }
            courseCalendarWrapper.setLinkProvider(
                new CourseLinkProviderController(
                    course, Collections.singletonList(course), ureq, wControl));
            calendars.add(courseCalendarWrapper);
          }
        } catch (CorruptedCourseException e) {
          OLATResource olatResource = courseEntry.getOlatResource();
          log.error(
              "Corrupted course: "
                  + olatResource.getResourceableTypeName()
                  + " :: "
                  + courseResourceableID,
              null);
        }
      }
    }
  }