package org.exoplatform.cs.job;

import java.util.Calendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import org.exoplatform.commons.utils.StringCommonUtils;
import org.exoplatform.container.ExoContainer;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.cs.dao.TopicDAO;
import org.exoplatform.cs.entity.TopicEntity;
import org.exoplatform.cs.service.util.ForumUtils;
import org.exoplatform.forum.service.Category;
import org.exoplatform.forum.service.Forum;
import org.exoplatform.forum.service.ForumService;
import org.exoplatform.forum.service.Topic;
import org.exoplatform.task.domain.Task;
import org.exoplatform.task.dto.TaskDto;
import org.exoplatform.task.exception.EntityNotFoundException;
import org.exoplatform.task.service.TaskService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by eXo Platform SAS.
 *
 * @author Ali Hamdi 
 * @since 23/08/17 17:39
 */

public class UpdateTopicEntityJob implements Job {
  private static final Logger LOG = LoggerFactory.getLogger(UpdateTopicEntityJob.class);



  @Override
  public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    ExoContainer containerContext = ExoContainerContext.getCurrentContainer();
    TopicDAO topicDAO = containerContext.getComponentInstanceOfType(TopicDAO.class);
    ForumService forumService = containerContext.getComponentInstanceOfType(ForumService.class);
    TaskService taskService = containerContext.getComponentInstanceOfType(TaskService.class);
    LOG.info("Start updating all tickets");
    List<TopicEntity> topics = topicDAO.getWithEmptyTicketID();
    for(TopicEntity topicEntity:topics){
      boolean updated = false;
      switch (topicEntity.getType()) {
        case INCIDENT:
        case INFORMATION:
          if(topicEntity.getTicketId() == null || topicEntity.getTicketId().isEmpty()){
            topicEntity.setTicketId(getTicketIdFromTitle(topicEntity));
            updated = true;
          }
          if(topicEntity.getCreationDate() == null || topicEntity.getTitle() == null || topicEntity.getTitle().isEmpty()){
            String topicId = topicEntity.getId();
            Category spaceCategory = forumService.getCategoryIncludedSpace();
            Forum forum = ForumUtils.getSpaceForum(forumService, topicEntity.getSpace().getGroupId());
            if (spaceCategory != null && forum != null) {
              try {
                Topic topic = forumService.getTopic(spaceCategory.getId(), forum.getId(), topicId, null);
                if (topicEntity.getCreationDate() == null) {
                  Calendar creationDate = Calendar.getInstance();
                  creationDate.setTime(topic.getCreatedDate());
                  topicEntity.setCreationDate(creationDate);
                  updated = true;
                }
                if (topicEntity.getTitle() == null || topicEntity.getTitle().isEmpty()) {
                  topicEntity.setTitle(StringCommonUtils.decodeSpecialCharToHTMLnumber(topic.getTopicName()));
                  updated = true;
                }
              } catch (Exception e) {
                LOG.error("Can not get data of Topic {}", topicId);
              }
            }
          }
          break;
        case PRODUCT:
          long taskId = Long.parseLong(topicEntity.getId());
          TaskDto task = null;
          try {
            task = taskService.getTask(taskId);
          } catch (EntityNotFoundException e) {
            LOG.warn("Task with id '{}' was not found", topicEntity.getId());
          }
          if (task == null) {
            break;
          }
          if(topicEntity.getCreationDate() == null){
            if (task.getStartDate() != null) {
              Calendar creationDate = Calendar.getInstance();
              creationDate.setTime(task.getStartDate());
              topicEntity.setCreationDate(creationDate);
              updated = true;
            }
          }
          if(topicEntity.getTitle() == null || topicEntity.getTitle().isEmpty()) {
            topicEntity.setTitle(task.getTitle());
            updated = true;
          }
          break;
        default:
          break;
      }

      if (updated) {
        long duration = System.currentTimeMillis();
        topicDAO.update(topicEntity);
        duration = System.currentTimeMillis() - duration;
        LOG.debug("Updating topic entity {} took {} ms", topicEntity.getTitle(), duration);
      }
    }
    LOG.info("All support tickets updated with the right project ID");
  }

  private String getTicketIdFromTitle (TopicEntity entity){
    String title = entity.getTitle();
    Pattern pattern = Pattern.compile("(?i)(\\[resolved\\])?[ ]*\\[(.+?)\\].*");
    Matcher matcher = pattern.matcher(title);
    if(matcher.find()) {
      return matcher.group(2);
    }
    return null;
  }
}
