// Copyright (C) 2014 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.google.gerrit.acceptance.server.project;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.junit.Assert.assertEquals;

import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.extensions.api.changes.CherryPickInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.LabelInfo;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.testutil.ConfigSuite;
import com.google.inject.Inject;

import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;

@NoHttpd
public class LabelTypeIT extends AbstractDaemonTest {
  @ConfigSuite.Config
  public static Config noteDbEnabled() {
    Config cfg = new Config();
    cfg.setBoolean("notedb", null, "write", true);
    cfg.setBoolean("notedb", "patchSetApprovals", "read", true);
    return cfg;
  }

  @Inject
  private GitRepositoryManager repoManager;

  @Inject
  private ProjectCache projectCache;

  @Inject
  private AllProjectsName allProjects;

  @Inject
  private MetaDataUpdate.Server metaDataUpdateFactory;

  private LabelType codeReview;

  @Before
  public void setUp() throws Exception {
    ProjectConfig cfg = projectCache.checkedGet(allProjects).getConfig();
    codeReview = checkNotNull(cfg.getLabelSections().get("Code-Review"));
    codeReview.setCopyMinScore(false);
    codeReview.setCopyMaxScore(false);
    codeReview.setCopyAllScoresOnTrivialRebase(false);
    codeReview.setCopyAllScoresIfNoCodeChange(false);
    codeReview.setDefaultValue((short)-1);
    saveProjectConfig(cfg);
  }

  @Test
  public void noCopyMinScoreOnRework() throws Exception {
    PushOneCommit.Result r = createChange();
    revision(r).review(ReviewInput.reject());
    assertApproval(r, -2);
    r = amendChange(r.getChangeId());
    assertApproval(r, 0);
  }

  @Test
  public void copyMinScoreOnRework() throws Exception {
    codeReview.setCopyMinScore(true);
    saveLabelConfig();
    PushOneCommit.Result r = createChange();
    revision(r).review(ReviewInput.reject());
    //assertApproval(r, -2);
    r = amendChange(r.getChangeId());
    assertApproval(r, -2);
  }

  @Test
  public void noCopyMaxScoreOnRework() throws Exception {
    PushOneCommit.Result r = createChange();
    revision(r).review(ReviewInput.approve());
    assertApproval(r, 2);
    r = amendChange(r.getChangeId());
    assertApproval(r, 0);
  }

  @Test
  public void copyMaxScoreOnRework() throws Exception {
    codeReview.setCopyMaxScore(true);
    saveLabelConfig();
    PushOneCommit.Result r = createChange();
    revision(r).review(ReviewInput.approve());
    assertApproval(r, 2);
    r = amendChange(r.getChangeId());
    assertApproval(r, 2);
  }

  @Test
  public void noCopyNonMaxScoreOnRework() throws Exception {
    codeReview.setCopyMinScore(true);
    codeReview.setCopyMaxScore(true);
    saveLabelConfig();

    PushOneCommit.Result r = createChange();
    revision(r).review(ReviewInput.recommend());
    assertApproval(r, 1);
    r = amendChange(r.getChangeId());
    assertApproval(r, 0);
  }

  @Test
  public void noCopyNonMinScoreOnRework() throws Exception {
    codeReview.setCopyMinScore(true);
    codeReview.setCopyMaxScore(true);
    saveLabelConfig();

    PushOneCommit.Result r = createChange();
    revision(r).review(ReviewInput.dislike());
    assertApproval(r, -1);
    r = amendChange(r.getChangeId());
    assertApproval(r, 0);
  }

  @Test
  public void noCopyAllScoresIfNoCodeChange() throws Exception {
    String file = "a.txt";
    String contents = "contents";

    PushOneCommit push = pushFactory.create(db, admin.getIdent(),
        "first subject", file, contents);
    PushOneCommit.Result r = push.to(git, "refs/for/master");
    revision(r).review(ReviewInput.recommend());
    assertApproval(r, 1);

    push = pushFactory.create(db, admin.getIdent(),
        "second subject", file, contents, r.getChangeId());
    r = push.to(git, "refs/for/master");
    assertApproval(r, 0);
  }

  @Test
  public void copyAllScoresIfNoCodeChange() throws Exception {
    String file = "a.txt";
    String contents = "contents";
    codeReview.setCopyAllScoresIfNoCodeChange(true);
    saveLabelConfig();

    PushOneCommit push = pushFactory.create(db, admin.getIdent(),
        "first subject", file, contents);
    PushOneCommit.Result r = push.to(git, "refs/for/master");
    revision(r).review(ReviewInput.recommend());
    assertApproval(r, 1);

    push = pushFactory.create(db, admin.getIdent(),
        "second subject", file, contents, r.getChangeId());
    r = push.to(git, "refs/for/master");
    assertApproval(r, 1);
  }

  @Test
  public void noCopyAllScoresOnTrivialRebase() throws Exception {
    String subject = "test commit";
    String file = "a.txt";
    String contents = "contents";

    PushOneCommit push = pushFactory.create(db, admin.getIdent());
    PushOneCommit.Result r1 = push.to(git, "refs/for/master");
    merge(r1);

    push = pushFactory.create(db, admin.getIdent(),
        "non-conflicting", "b.txt", "other contents");
    PushOneCommit.Result r2 = push.to(git, "refs/for/master");
    merge(r2);

    git.checkout().setName(r1.getCommit().name()).call();
    push = pushFactory.create(db, admin.getIdent(), subject, file, contents);
    PushOneCommit.Result r3 = push.to(git, "refs/for/master");
    revision(r3).review(ReviewInput.recommend());
    assertApproval(r3, 1);

    rebase(r3);
    assertApproval(r3, 0);
  }

  @Test
  public void copyAllScoresOnTrivialRebase() throws Exception {
    String subject = "test commit";
    String file = "a.txt";
    String contents = "contents";
    codeReview.setCopyAllScoresOnTrivialRebase(true);
    saveLabelConfig();

    PushOneCommit push = pushFactory.create(db, admin.getIdent());
    PushOneCommit.Result r1 = push.to(git, "refs/for/master");
    merge(r1);

    push = pushFactory.create(db, admin.getIdent(),
        "non-conflicting", "b.txt", "other contents");
    PushOneCommit.Result r2 = push.to(git, "refs/for/master");
    merge(r2);

    git.checkout().setName(r1.getCommit().name()).call();
    push = pushFactory.create(db, admin.getIdent(), subject, file, contents);
    PushOneCommit.Result r3 = push.to(git, "refs/for/master");
    revision(r3).review(ReviewInput.recommend());
    assertApproval(r3, 1);

    rebase(r3);
    assertApproval(r3, 1);
  }

  @Test
  public void copyAllScoresOnTrivialRebaseAndCherryPick() throws Exception {
    codeReview.setCopyAllScoresOnTrivialRebase(true);
    saveLabelConfig();

    PushOneCommit.Result r1 = createChange();
    git.checkout().setName(r1.getCommit().name()).call();

    PushOneCommit push = pushFactory.create(db, admin.getIdent(),
        PushOneCommit.SUBJECT, "b.txt", "other contents");
    PushOneCommit.Result r2 = push.to(git, "refs/for/master");

    revision(r2).review(ReviewInput.recommend());

    CherryPickInput in = new CherryPickInput();
    in.destination = "master";
    in.message = String.format("%s\n\nChange-Id: %s",
        PushOneCommit.SUBJECT,
        r2.getChangeId());

    doAssertApproval(1,
        gApi.changes()
            .id(r2.getChangeId())
            .revision(r2.getCommit().name())
            .cherryPick(in)
            .get());
  }

  @Test
  public void copyNoScoresOnReworkAndCherryPick()
      throws Exception {
    codeReview.setCopyAllScoresOnTrivialRebase(true);
    saveLabelConfig();

    PushOneCommit.Result r1 = createChange();

    git.checkout().setName(r1.getCommit().name()).call();

    PushOneCommit push = pushFactory.create(db, admin.getIdent(),
        PushOneCommit.SUBJECT, "b.txt", "other contents");
    PushOneCommit.Result r2 = push.to(git, "refs/for/master");

    revision(r2).review(ReviewInput.recommend());

    CherryPickInput in = new CherryPickInput();
    in.destination = "master";
    in.message = String.format("Cherry pick\n\nChange-Id: %s",
        r2.getChangeId());

    doAssertApproval(0,
        gApi.changes()
            .id(r2.getChangeId())
            .revision(r2.getCommit().name())
            .cherryPick(in)
            .get());
  }

  private void saveLabelConfig() throws Exception {
    ProjectConfig cfg = projectCache.checkedGet(allProjects).getConfig();
    cfg.getLabelSections().clear();
    cfg.getLabelSections().put(codeReview.getName(), codeReview);
    saveProjectConfig(cfg);
  }

  private void saveProjectConfig(ProjectConfig cfg) throws Exception {
    MetaDataUpdate md = metaDataUpdateFactory.create(allProjects);
    try {
      cfg.commit(md);
    } finally {
      md.close();
    }
  }

  private void merge(PushOneCommit.Result r) throws Exception {
    revision(r).review(ReviewInput.approve());
    revision(r).submit();
    Repository repo = repoManager.openRepository(project);
    try {
      assertEquals(r.getCommitId(),
          repo.getRef("refs/heads/master").getObjectId());
    } finally {
      repo.close();
    }
  }

  private void rebase(PushOneCommit.Result r) throws Exception {
    revision(r).rebase();
  }

  private void assertApproval(PushOneCommit.Result r, int expected)
      throws Exception {
    // Don't use asserts from PushOneCommit so we can test the round-trip
    // through JSON instead of querying the DB directly.
    ChangeInfo c = get(r.getChangeId());
    doAssertApproval(expected, c);
  }

  private void doAssertApproval(int expected, ChangeInfo c) {
    LabelInfo cr = c.labels.get("Code-Review");
    assertEquals(-1, (int) cr.defaultValue);
    assertEquals(1, cr.all.size());
    assertEquals("Administrator", cr.all.get(0).name);
    assertEquals(expected, cr.all.get(0).value.intValue());
  }
}
