001/*
002 *  Copyright 2024 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.odf.tree;
017
018import java.util.List;
019import java.util.Map;
020
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023
024import org.ametys.cms.repository.Content;
025import org.ametys.odf.ODFHelper;
026import org.ametys.odf.ProgramItem;
027import org.ametys.odf.data.EducationalPath;
028import org.ametys.odf.program.Program;
029import org.ametys.odf.tree.ODFTreeIndicator.IndicatorData;
030import org.ametys.plugins.repository.AmetysObjectResolver;
031import org.ametys.runtime.i18n.I18nizableText;
032import org.ametys.runtime.i18n.I18nizableTextParameter;
033
034/**
035 * {@link ODFTreeIndicator} to display the share status
036 */
037public class ShareStatusIndicator extends AbstractStaticODFTreeIndicator
038{
039    private ODFHelper _odfHelper;
040    private AmetysObjectResolver _resolver;
041
042    @Override
043    public void service(ServiceManager smanager) throws ServiceException
044    {
045        super.service(smanager);
046        _odfHelper = (ODFHelper) smanager.lookup(ODFHelper.ROLE);
047        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
048    }
049    
050    public IndicatorData getIndicatorData(Content content)
051    {
052        if (content instanceof ProgramItem programItem)
053        {
054            int nbParents = _odfHelper.getParentProgramItems(programItem).size();
055            boolean isShared = nbParents > 1;
056            boolean isSharedByParents = !isShared ? _isSharedByParents(programItem) : false;
057            
058            if (isShared)
059            {
060                long nbOrphanParents = _nbOrphanParents(programItem);
061                if (nbOrphanParents > 0)
062                {
063                    // Program item is shared with orphan parents
064                    Map<String, I18nizableTextParameter> i18nParams = Map.of("nbParents", new I18nizableText(String.valueOf(nbParents)), 
065                            "nbOrphanParents", new I18nizableText(String.valueOf(nbOrphanParents)));
066                    return new IndicatorData(new I18nizableText("plugin.odf", "PLUGINS_ODF_CONTENTS_TREE_INDICATORS_SHARED_WITH_ORPHANS", i18nParams), null, "odficon-share-filled orange-color", Map.of());
067                }
068                else
069                {
070                    Map<String, I18nizableTextParameter> i18nParams = Map.of("nbParents", new I18nizableText(String.valueOf(nbParents)));
071                    return new IndicatorData(new I18nizableText("plugin.odf", "PLUGINS_ODF_CONTENTS_TREE_INDICATORS_SHARED", i18nParams), null, "odficon-share-filled", Map.of());
072                }
073            }
074            else if (isSharedByParents)
075            {
076                return new IndicatorData(new I18nizableText("plugin.odf", "PLUGINS_ODF_CONTENTS_TREE_INDICATORS_PARENT_SHARED"), null, "odficon-share-outline", Map.of());
077            }
078        }
079        
080        return null;
081    }
082    
083    private long _nbOrphanParents(ProgramItem programItem)
084    {
085        List<EducationalPath> educationalPaths = _odfHelper.getEducationalPaths(programItem);
086        
087        return educationalPaths.stream()
088            .filter(p -> !(p.getProgramItems(_resolver).get(0) instanceof Program))
089            .count();
090    }
091    
092    private boolean _isShared(ProgramItem programItem)
093    {
094        return _odfHelper.getParentProgramItems(programItem).size() > 1;
095    }
096    
097    private boolean _isSharedByParents(ProgramItem programItem)
098    {
099        for (ProgramItem parent : _odfHelper.getParentProgramItems(programItem))
100        {
101            return _isShared(programItem) ? true : _isSharedByParents(parent);
102        }
103        return false;
104    }
105
106}