package com.atlassian.stash.internal.notification.commit.handlers;

import com.atlassian.bitbucket.commit.Commit;
import com.atlassian.bitbucket.commit.CommitDiscussion;
import com.atlassian.bitbucket.commit.CommitRequest;
import com.atlassian.bitbucket.commit.CommitService;
import com.atlassian.bitbucket.i18n.I18nKey;
import com.atlassian.stash.internal.notification.handlers.AbstractNotificationHandler;
import com.atlassian.stash.internal.notification.handlers.NotificationHelper;
import com.atlassian.stash.internal.notification.handlers.WatchableMailThreadHeaderTransformer;
import com.atlassian.stash.internal.notification.usersettings.SendMode;
import com.atlassian.bitbucket.mail.MailMessage;
import com.atlassian.bitbucket.notification.commit.CommitDiscussionNotification;
import com.atlassian.bitbucket.repository.Repository;

import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AbstractCommitDiscussionNotificationHandler<T extends CommitDiscussionNotification>
        extends AbstractNotificationHandler<T> {

    public static final Pattern PATTERN_SUBJECT = Pattern.compile("(?:\\.\\s)|\n");

    private static final int SUMMARY_MAX_LENGTH = 100;

    private final CommitService commitService;

    public AbstractCommitDiscussionNotificationHandler(NotificationHelper helper, CommitService commitService,
                                                       String templateName) {
        super(helper, templateName);
        this.commitService = commitService;
    }

    @Override
    protected Map<String, Object> getContext(T notification) {
        Map<String, Object> context = super.getContext(notification);
        context.put("commitDiscussion", notification.getCommitDiscussion());
        return context;
    }

    @Override
    protected I18nKey generateSubjectKey(CommitDiscussionNotification notification) {
        CommitDiscussion commitDiscussion = notification.getCommitDiscussion();
        Repository repository = commitDiscussion.getRepository();
        Commit commit = commitService.getCommit(new CommitRequest.Builder(repository, commitDiscussion.getCommitId()).build());

        return new I18nKey("bitbucket.notification.email.commitdiscussion.title",
                repository.getProject().getKey(),
                repository.getName(),
                commit.getDisplayId(),
                summarize(commit.getMessage()));
    }

    @Override
    protected Function<MailMessage.Builder, MailMessage.Builder> getMessageTransformer(CommitDiscussionNotification notification) {
        return new WatchableMailThreadHeaderTransformer(notification.getCommitDiscussion());
    }

    @Override
    protected Set<SendMode> getEnabledSendModes() {
        // Commit discussion notifications are not batched yet, so send them right away regardless of preference
        return SendMode.batchedAndImmediateSet();
    }

    static String summarize(String message) {
        Matcher matcher = PATTERN_SUBJECT.matcher(message);

        String summary = matcher.find() ? message.substring(0, matcher.end()).trim() : message;

        if (summary.length() > SUMMARY_MAX_LENGTH) {
            summary = summary.substring(0, SUMMARY_MAX_LENGTH);
        }

        return summary;
    }
}