package com.alexander.plugins.commitmessage;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vcs.CheckinProjectPanel;
import com.intellij.openapi.vcs.changes.CommitExecutor;
import com.intellij.openapi.vcs.checkin.CheckinHandler;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
import com.intellij.ui.NonFocusableCheckBox;
import com.intellij.util.PairConsumer;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;

public class CheckCommitMessageCheckinHandler extends CheckinHandler {

	protected final Project myProject;
	private final CheckinProjectPanel myPanel;
	private static final Logger LOG = Logger.getInstance("#" + CheckCommitMessageCheckinHandler.class.getName());

	private static final int COMMIT_TITLE_LENGTH = 50;

	public CheckCommitMessageCheckinHandler(final Project project, final CheckinProjectPanel panel) {
		myProject = project;
		myPanel = panel;
	}

	@Override
	@Nullable
	public RefreshableOnComponent getBeforeCheckinConfigurationPanel() {
		final JCheckBox checkMessageBox = new NonFocusableCheckBox("Check commit message");

		return new RefreshableOnComponent() {
			@Override
			public JComponent getComponent() {
				final JPanel panel = new JPanel(new GridLayout(1, 0));
				panel.add(checkMessageBox);
				return panel;
			}

			@Override
			public void refresh() {
			}

			@Override
			public void saveState() {
				getSettings().CHECK_COMMIT_MESSAGE = checkMessageBox.isSelected();
			}

			@Override
			public void restoreState() {
				checkMessageBox.setSelected(getSettings().CHECK_COMMIT_MESSAGE);
			}
		};
	}

	protected CommitMessageConfiguration getSettings() {
		return CommitMessageConfiguration.getInstance(myProject);
	}

	@Override
	public ReturnResult beforeCheckin(CommitExecutor executor, PairConsumer<Object, Object> additionalDataConsumer) {
		if (getSettings().CHECK_COMMIT_MESSAGE) {
			String wholeCommitMessage = myPanel.getCommitMessage();

			if (wholeCommitMessage == null){
				return ReturnResult.COMMIT; // leave the error msg to the soruce code
			}

			String[] commitParts = wholeCommitMessage.split("\n\n");
			String commitTitle = commitParts[0];

			if (commitTitle.length() > COMMIT_TITLE_LENGTH) {
				Messages.showErrorDialog(myProject, "Commit subject line is too long", "Commit Message");
				return ReturnResult.CANCEL;
			}

			return ReturnResult.COMMIT;
		} else {
			return ReturnResult.COMMIT;
		}
	}
}

@@ -2087,17 +2087,58 @@
  == null
-)
+ %7C%7C wholeCommitMessage.trim().equals(%22%22)) 
 %7B%0A%09%09%09%09re
@@ -2199,10 +2199,10 @@
 e so
-r
 u
+r
 ce c
@@ -2312,16 +2312,42 @@
 ts%5B0%5D;%0A%0A
+%09%09%09String errorMsg = %22%22;%0A%0A
 %09%09%09if (c
@@ -2399,77 +2399,386 @@
 %09%09%09%09
-Messages.showErrorDialog(myProject, %22Commit subject line is too long%22
+errorMsg += %22 - Subject line is too long%22;%0A%09%09%09%7D%0A%09%09%09if (!Character.isUpperCase(commitTitle.codePointAt(0))) %7B%0A%09%09%09%09errorMsg += %22%5Cn - Subject line should start with a capital letter%22;%0A%09%09%09%7D%0A%09%09%09if (commitTitle.trim().endsWith(%22.%22)) %7B%0A%09%09%09%09errorMsg += %22%5Cn - Subject line should not end with period%22;%0A%09%09%09%7D%0A%0A%09%09%09if (!errorMsg.equals(%22%22)) %7B%0A%09%09%09%09Messages.showErrorDialog(myProject, errorMsg
 , %22C
@@ -2786,24 +2786,30 @@
 mmit Message
+ Error
 %22);%0A%09%09%09%09retu
@@ -2841,52 +2841,12 @@
 %09%09%7D%0A
-%0A%09%09%09return ReturnResult.COMMIT;%0A%09%09%7D else %7B%0A%09
+%09%09%7D%0A
 %09%09re
@@ -2871,17 +2871,13 @@
 COMMIT;%0A
-%09%09%7D%0A
 %09%7D%0A%7D%0A

Add more error scenarios to commit message