// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.googlesource.gerrit.plugins.validators;

import com.google.gerrit.extensions.annotations.Listen;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.events.CommitReceivedEvent;
import com.google.gerrit.server.git.validators.CommitValidationException;
import com.google.gerrit.server.git.validators.CommitValidationListener;
import com.google.gerrit.server.git.validators.CommitValidationMessage;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.revwalk.RevCommit;

@Listen
@Singleton
public class CommitMessageLengthValidation implements CommitValidationListener {
  private static final int DEFAULT_MAX_SUBJECT_LENGTH = 50;
  private static final int DEFAULT_MAX_LINE_LENGTH = 72;
  private static final int DEFAULT_LONG_LINES_THRESHOLD = 33;
  private static final boolean DEFAULT_REJECT_TOO_LONG = false;
  private static final String COMMIT_MESSAGE_SECTION = "commitmessage";
  private static final String MAX_SUBJECT_LENGTH_KEY = "maxSubjectLength";
  private static final String MAX_LINE_LENGTH_KEY = "maxLineLength";
  private static final String REJECT_TOO_LONG_KEY = "rejectTooLong";
  private static final String LONG_LINES_THRESHOLD_KEY = "longLinesThreshold";

  private final Config config;
  private final int maxSubjectLength;
  private final int maxLineLength;
  private final int longLinesThreshold;
  private boolean rejectTooLong;

  @Inject
  public CommitMessageLengthValidation(@GerritServerConfig Config gerritConfig) {
    this.config = gerritConfig;
    this.maxSubjectLength = nonNegativeInt(MAX_SUBJECT_LENGTH_KEY, DEFAULT_MAX_SUBJECT_LENGTH);
    this.maxLineLength = nonNegativeInt(MAX_LINE_LENGTH_KEY, DEFAULT_MAX_LINE_LENGTH);
    this.rejectTooLong =
        config.getBoolean(COMMIT_MESSAGE_SECTION, REJECT_TOO_LONG_KEY, DEFAULT_REJECT_TOO_LONG);
    this.longLinesThreshold =
        nonNegativeInt(LONG_LINES_THRESHOLD_KEY, DEFAULT_LONG_LINES_THRESHOLD);
  }

  private int nonNegativeInt(String name, int defaultValue) {
    int value = this.config.getInt(COMMIT_MESSAGE_SECTION, null, name, defaultValue);
    return value >= 0 ? value : defaultValue;
  }

  private void onLineTooLong(
      final AbbreviatedObjectId id,
      List<CommitValidationMessage> messagesList,
      final String errorMessage)
      throws CommitValidationException {
    final String message = id.name() + ": " + errorMessage;
    if (rejectTooLong) {
      messagesList.add(new CommitValidationMessage(message, true));
      throw new CommitValidationException("Commit length validation failed", messagesList);
    }
    messagesList.add(new CommitValidationMessage("(W) " + message, false));
  }

  @Override
  public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
      throws CommitValidationException {
    final RevCommit commit = receiveEvent.commit;
    final AbbreviatedObjectId id = commit.abbreviate(7);
    List<CommitValidationMessage> messages = new ArrayList<>();

    if (this.maxSubjectLength < commit.getShortMessage().length()) {
      onLineTooLong(
          id,
          messages,
          "commit subject >" + this.maxSubjectLength + " characters; use shorter first paragraph");
    }

    int longLineCnt = 0;
    int nonEmptyCnt = 0;
    for (String line : commit.getFullMessage().split("\n")) {
      if (!line.trim().isEmpty()) {
        nonEmptyCnt++;
      }
      if (this.maxLineLength < line.length()) {
        longLineCnt++;
      }
    }

    if (longLineCnt > (longLinesThreshold * nonEmptyCnt) / 100) {
      onLineTooLong(
          id,
          messages,
          "too many commit message lines longer than "
              + this.maxLineLength
              + " characters; manually wrap lines");
    }

    return messages;
  }
}
