package com.ullink.slack.review.gerrit;
import java.util.ArrayList;
import java.util.Date;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import com.google.common.html.HtmlEscapers;
import com.ullink.slack.review.Constants;
import com.ullink.slack.review.gerrit.ChangeInfo.IssuePriority;
import com.ullink.slack.simpleslackapi.SlackAttachment;
import com.ullink.slack.simpleslackapi.SlackSession;
import com.ullink.slack.simpleslackapi.SlackUser;
public class DefaultChangeInfoFormatter implements ChangeInfoFormatter
{
protected final String gerritURL;
protected final String jiraURL;
public DefaultChangeInfoFormatter(Properties properties)
{
this.gerritURL = properties.getProperty(Constants.GERRIT_URL);
this.jiraURL = properties.getProperty(Constants.JIRA_URL);
}
@Override
public SlackAttachment createAttachment(String changeId, ChangeInfo changeInfo, SlackSession session)
{
SlackAttachment attachment = new SlackAttachment();
attachment.addMarkdownIn("fields");
attachment.addMarkdownIn("pretext");
String subject = HtmlEscapers.htmlEscaper().escape(changeInfo.getSubject());
String pretext = "*<" + gerritURL + changeId + "/" + "|" + subject + " (#" + changeId + ")>* *owner :* " + formatOwnerInfo(changeInfo, session);
if (changeInfo.getCherryPickedFrom() != null)
{
pretext += " *Cherry picked from :* *<" + gerritURL + changeInfo.getCherryPickedFrom() + "/" + "| #" + changeInfo.getCherryPickedFrom() + ">*";
}
attachment.setPretext(pretext);
attachment.addField(null, formatProjectInfo(changeInfo) + " " + formatLastUpdatedInfo(changeInfo), false);
String issuesDescription = formatRelatedIssues(changeInfo);
if (issuesDescription != null)
{
attachment.addField(null, issuesDescription, true);
}
return attachment;
}
protected String formatRelatedIssues(ChangeInfo changeInfo)
{
Map<String, JIRAInfo> relatedIssuesByIssue = changeInfo.getRelatedJira();
if (relatedIssuesByIssue == null || relatedIssuesByIssue.isEmpty())
{
return null;
}
EnumMap<IssuePriority, List<JIRAInfo>> relatedIssuesByPriority = new EnumMap<>(IssuePriority.class);
for (Entry<String, JIRAInfo> entry : relatedIssuesByIssue.entrySet())
{
List<JIRAInfo> priorityIssues = relatedIssuesByPriority.get(entry.getValue().getPriority());
if (priorityIssues == null)
{
priorityIssues = new ArrayList<>();
relatedIssuesByPriority.put(entry.getValue().getPriority(), priorityIssues);
}
priorityIssues.add(entry.getValue());
}
StringBuilder builder = new StringBuilder();
builder.append("*Issues :* ");
boolean first = true;
for (Entry<IssuePriority, List<JIRAInfo>> entry : relatedIssuesByPriority.entrySet())
{
for (JIRAInfo relatedIssue : entry.getValue())
{
if (first)
{
first = false;
}
else
{
builder.append(", ");
}
displayRelatedIssue(builder, relatedIssue);
}
}
return builder.toString();
}
protected void displayRelatedIssue(StringBuilder builder, JIRAInfo jiraData)
{
builder.append('<').append(jiraURL).append(jiraData.getJiraId()).append('|').append(' ').append(jiraData.getJiraId()).append('>');
}
protected String displayUser(SlackUser user)
{
String realName = user.getUserName();
if (realName == null || realName.isEmpty())
{
return "<@" + user.getId() + ">";
}
return realName + " (<@" + user.getId() + ">)";
}
protected String formatOwnerInfo(ChangeInfo changeInfo, SlackSession session)
{
return "`" + displayUser(session, changeInfo.getOwnerEmail(), changeInfo.getOwner()) + "`";
}
protected String displayUser(SlackSession session, String email, String name)
{
SlackUser user = session.findUserByEmail(email);
if (user == null)
{
return name;
}
return displayUser(user);
}
protected String formatProjectInfo(ChangeInfo changeInfo)
{
return "*Project:* " + changeInfo.getProject() + ":" + "`" + changeInfo.getBranch() + "`";
}
protected String formatLastUpdatedInfo(ChangeInfo changeInfo)
{
return "*Updated:* _" + formatUpdatedField(changeInfo.getUpdated()) + "_";
}
protected String formatUpdatedField(Date updateDate)
{
Date now = new Date();
long nbDaysFromNow = (now.getTime() - updateDate.getTime()) / (1000l * 60 * 60 * 24);
if (nbDaysFromNow <= 0)
{
long nbHoursFromNow = (now.getTime() - updateDate.getTime()) / (1000l * 60 * 60);
if (nbHoursFromNow <= 0)
{
long nbMinutesFromNow = (now.getTime() - updateDate.getTime()) / (1000l * 60);
if (nbMinutesFromNow <= 0)
{
return "Less than a minute ago";
}
else
{
if (nbMinutesFromNow == 1)
{
return "One minute ago";
}
return nbMinutesFromNow + " minutes ago";
}
}
else
{
if (nbHoursFromNow == 1)
{
return "One hour ago";
}
return nbHoursFromNow + " hours ago";
}
}
else
{
if (nbDaysFromNow == 1)
{
return "One day ago";
}
return nbDaysFromNow + " days ago";
}
}
}