package com.atolcd.parapheur.repo.patch;

import java.util.List;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.atolcd.parapheur.model.ParapheurModel;

public class ArchivesFormatPatch extends AbstractPatch
{
   private static Log logger = LogFactory.getLog(ArchivesFormatPatch.class);
   
   private ContentService contentService;
   private ImporterBootstrap spacesBootstrap;
   
   /**
    * @param contentService The contentService to set.
    */
   public void setContentService(ContentService contentService)
   {
      this.contentService = contentService;
   }

   /**
    * @param spacesBootstrap The spacesBootstrap to set.
    */
   public void setSpacesBootstrap(ImporterBootstrap spacesBootstrap)
   {
      this.spacesBootstrap = spacesBootstrap;
   }

   /**
    * @param nodeService The nodeService to set.
    */
   public void setNodeService(NodeService nodeService)
   {
      this.nodeService = nodeService;
   }

   /**
    * @param searchService The searchService to set.
    */
   public void setSearchService(SearchService searchService)
   {
      this.searchService = searchService;
   }

   @Override
   protected String applyInternal() throws Exception
   {
      String msg = "Patch Parapheur 2 applique avec succes";
      
      // Récupération du répertoire des archives
      List<NodeRef> results = null;
      String archivesFolderPath = "/app:company_home/ph:archives";
      NodeRef rootNodeRef = nodeService.getRootNode(spacesBootstrap.getStoreRef());
      results = searchService.selectNodes(rootNodeRef, archivesFolderPath, null, namespaceService, false);
      
      if (results == null || results.size() != 1)
      {
         msg = "Impossible de trouver le répertoire d'archives";
         throw new PatchException(msg);
      }
      NodeRef archivesRef = results.get(0);
      
      List<ChildAssociationRef> children = nodeService.getChildAssocs(archivesRef);
      for (ChildAssociationRef child : children)
      {
         NodeRef archive = child.getChildRef();
         if (nodeService.exists(archive)
          && ContentModel.TYPE_CONTENT.equals(nodeService.getType(archive))
          && !nodeService.hasAspect(archive, ParapheurModel.ASPECT_SIGNED))
         {
            ContentReader reader = contentService.getReader(archive, ContentModel.PROP_CONTENT);
            if (MimetypeMap.MIMETYPE_PDF.equals(reader.getMimetype()))
            {
               String name = (String)nodeService.getProperty(archive, ContentModel.PROP_NAME);
               NodeRef docRef = null,
                       sigRef = null;
               for (ChildAssociationRef tmpChild : children)
               {
                  if (docRef != null && sigRef != null)
                     break;
                  else
                  {
                     NodeRef tmpChildRef = tmpChild.getChildRef();
                     if (nodeService.exists(tmpChildRef))
                     {
                        String tmpName = (String) nodeService.getProperty(tmpChildRef, ContentModel.PROP_NAME);
                        if (tmpName.equals(name+".old"))
                        {
                           docRef = tmpChildRef;
                        }
                        else if (tmpName.equals(name+".p7s"))
                        {
                           sigRef = tmpChildRef;
                        }
                     }
                  }
               }
               if (docRef != null && sigRef != null)
               {
                  nodeService.addAspect(archive, ParapheurModel.ASPECT_SIGNED, null);
                  
                  String originalName = "Document original";
                  nodeService.setProperty(archive, ParapheurModel.PROP_ORIGINAL_NAME, originalName);
                  
                  ContentReader tmpReader = contentService.getReader(docRef, ContentModel.PROP_CONTENT);
                  ContentWriter tmpWriter = contentService.getWriter(archive, ParapheurModel.PROP_ORIGINAL, true);
                  tmpWriter.setEncoding(tmpReader.getEncoding());
                  tmpWriter.setMimetype(tmpReader.getMimetype());
                  tmpWriter.putContent(tmpReader);
                  
                  tmpReader = contentService.getReader(sigRef, ContentModel.PROP_CONTENT);
                  tmpWriter = contentService.getWriter(archive, ParapheurModel.PROP_SIG, true);
                  tmpWriter.setEncoding(tmpReader.getEncoding());
                  tmpWriter.setMimetype(tmpReader.getMimetype());
                  tmpWriter.putContent(tmpReader);
                  
                  nodeService.deleteNode(docRef);
                  nodeService.deleteNode(sigRef);
               }
            }
         }
      }
      
      return msg;
   }
   
   protected void checkProperties()
   {
      try
      {
         super.checkProperties();
      }
      catch (Exception e)
      {
         logger.error("Erreur de pptes dans le patch 2",e);
      }
   }
}
