001/*
002 *  Copyright 2025 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.workspaces.calendars.task;
017
018import java.time.ZonedDateTime;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022import java.util.UUID;
023
024import org.apache.commons.lang3.StringUtils;
025
026import org.ametys.plugins.explorer.resources.jcr.JCRResourcesCollection;
027import org.ametys.plugins.repository.AmetysRepositoryException;
028import org.ametys.plugins.workspaces.calendars.Calendar;
029import org.ametys.plugins.workspaces.calendars.ModifiableCalendar;
030import org.ametys.plugins.workspaces.calendars.events.CalendarEvent;
031import org.ametys.plugins.workspaces.calendars.events.CalendarEventOccurrence;
032import org.ametys.plugins.workspaces.project.objects.Project;
033import org.ametys.plugins.workspaces.tasks.WorkspaceTaskDAO;
034
035/**
036 * Task calendar object
037 */
038public class TaskCalendar implements ModifiableCalendar
039{
040    /** The attribute name to detect is the task calendar is disabled */
041    public static final String TASK_CALENDAR_DISABLED_ATTR = "taskCalendarDisabled";
042    
043    /** The attribute name for the task calendar name */
044    public static final String TASK_CALENDAR_NAME_ATTR = "taskCalendarName";
045    
046    /** The attribute name for the task calendar token */
047    public static final String TASK_CALENDAR_TOKEN_ATTR = "taskCalendarToken";
048    
049    /** The attribute name for the task calendar visibility */
050    public static final String TASK_CALENDAR_VISIBILITY_ATTR = "taskCalendarVisibility";
051    
052    /** The attribute name for the task calendar color */
053    public static final String TASK_CALENDAR_COLOR_ATTR = "taskCalendarColor";
054    
055    
056    private WorkspaceTaskDAO _taskDAO;
057    private Project _project;
058    private JCRResourcesCollection _calendarModuleRoot;
059    /**
060     * The constructor
061     * @param project the project
062     * @param calendarModuleRoot the calendar module root
063     * @param taskDAO the task DAO
064     */
065    public TaskCalendar(Project project, JCRResourcesCollection calendarModuleRoot, WorkspaceTaskDAO taskDAO)
066    {
067        _project = project;
068        _taskDAO = taskDAO;
069        _calendarModuleRoot = calendarModuleRoot;
070    }
071    
072    /**
073     * <code>true</code> if the calendar is disabled
074     * @return <code>true</code> if the calendar is disabled
075     */
076    public boolean isDisabled()
077    {
078        return _calendarModuleRoot.getValue(TASK_CALENDAR_DISABLED_ATTR, false);
079    }
080    
081    /**
082     * Disable the task calendar
083     * @param disabled <code>true</code> to disable the task calendar
084     */
085    public void disable(boolean disabled)
086    {
087        _calendarModuleRoot.setValue(TASK_CALENDAR_DISABLED_ATTR, disabled);
088        _calendarModuleRoot.saveChanges();
089    }
090    
091    public String getId() throws AmetysRepositoryException
092    {
093        return TaskCalendar.class.getName();
094    }
095    
096    public String getName() throws AmetysRepositoryException
097    {
098        return _calendarModuleRoot.getValue(TASK_CALENDAR_NAME_ATTR, StringUtils.EMPTY);
099    }
100    
101    public void rename(String name)
102    {
103        _calendarModuleRoot.setValue(TASK_CALENDAR_NAME_ATTR, name);
104        _calendarModuleRoot.saveChanges();        
105    }
106    
107    public Project getProject()
108    {
109        return _project;
110    }
111    
112    public String getColor()
113    {
114        return _calendarModuleRoot.getValue(TASK_CALENDAR_COLOR_ATTR, "col1");
115    }
116
117    public void setColor(String color)
118    {
119        _calendarModuleRoot.setValue(TASK_CALENDAR_COLOR_ATTR, color);
120        _calendarModuleRoot.saveChanges();
121    }
122    
123    public CalendarVisibility getVisibility()
124    {
125        return CalendarVisibility.valueOf(_calendarModuleRoot.getValue(TASK_CALENDAR_VISIBILITY_ATTR, CalendarVisibility.PRIVATE.name()));
126    }
127
128    public void setVisibility(CalendarVisibility visibility)
129    {
130        _calendarModuleRoot.setValue(TASK_CALENDAR_VISIBILITY_ATTR, visibility.name());
131        _calendarModuleRoot.saveChanges();
132    }
133    
134    public String getIcsUrlToken()
135    {
136        String token = _calendarModuleRoot.getValue(TASK_CALENDAR_TOKEN_ATTR);
137        if (StringUtils.isBlank(token))
138        {
139            token = UUID.randomUUID().toString();
140            setIcsUrlToken(token);
141        }
142        return token;
143    }
144
145    public void setIcsUrlToken(String token)
146    {
147        _calendarModuleRoot.setValue(TASK_CALENDAR_TOKEN_ATTR, token);
148        _calendarModuleRoot.saveChanges();
149
150    }
151    
152    public String getDescription()
153    {
154        return null;
155    }
156    
157    public void setDescription(String desc)
158    {
159        // Do nothing
160    }
161    
162    public String getTemplateDescription()
163    {
164        return null;
165    }
166    
167    public void setTemplateDescription(String templateDesc)
168    {
169        // Do nothing
170    }
171
172    public List<Calendar> getChildCalendars()
173    {
174        return List.of();
175    }
176    
177    public List<CalendarEvent> getAllEvents()
178    {
179        if (isDisabled())
180        {
181            return List.of();
182        }
183        
184        return _taskDAO.getProjectTasks(_project)
185                    .stream()
186                    .filter(t -> t.getStartDate() != null || t.getDueDate() != null)
187                    .map(t -> new TaskCalendarEvent(this, t))
188                    .map(CalendarEvent.class::cast)
189                    .toList();
190    }
191    
192    public Map<CalendarEvent, List<CalendarEventOccurrence>> getEvents(ZonedDateTime startDate, ZonedDateTime endDate)
193    {
194        Map<CalendarEvent, List<CalendarEventOccurrence>> events = new HashMap<>();
195        
196        for (CalendarEvent event : getAllEvents())
197        {
198            List<CalendarEventOccurrence> occurences = event.getOccurrences(startDate, endDate);
199            if (!occurences.isEmpty())
200            {
201                events.put(event, occurences);
202            }
203        }
204        
205        return events;
206    }
207}