// Copyright (C) 2011 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.server.git;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.google.common.collect.Iterables;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.ContributorAgreement;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;

import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.util.RawParseUtils;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;

public class ProjectConfigTest extends LocalDiskRepositoryTestCase {
  private final GroupReference developers = new GroupReference(
      new AccountGroup.UUID("X"), "Developers");
  private final GroupReference staff = new GroupReference(
      new AccountGroup.UUID("Y"), "Staff");

  private Repository db;
  private TestRepository<Repository> util;

  @Override
  @Before
  public void setUp() throws Exception {
    super.setUp();
    db = createBareRepository();
    util = new TestRepository<>(db);
  }

  @Test
  public void testReadConfig() throws Exception {
    RevCommit rev = util.commit(util.tree( //
        util.file("groups", util.blob(group(developers))), //
        util.file("project.config", util.blob(""//
            + "[access \"refs/heads/*\"]\n" //
            + "  exclusiveGroupPermissions = read submit create\n" //
            + "  submit = group Developers\n" //
            + "  push = group Developers\n" //
            + "  read = group Developers\n" //
            + "[accounts]\n" //
            + "  sameGroupVisibility = deny group Developers\n" //
            + "  sameGroupVisibility = block group Staff\n" //
            + "[contributor-agreement \"Individual\"]\n" //
            + "  description = A simple description\n" //
            + "  accepted = group Developers\n" //
            + "  accepted = group Staff\n" //
            + "  requireContactInformation = true\n" //
            + "  autoVerify = group Developers\n" //
            + "  agreementUrl = http://www.example.com/agree\n")) //
        ));

    ProjectConfig cfg = read(rev);
    assertEquals(2, cfg.getAccountsSection().getSameGroupVisibility().size());
    ContributorAgreement ca = cfg.getContributorAgreement("Individual");
    assertEquals("Individual", ca.getName());
    assertEquals("A simple description", ca.getDescription());
    assertEquals("http://www.example.com/agree", ca.getAgreementUrl());
    assertEquals(2, ca.getAccepted().size());
    assertEquals(developers, ca.getAccepted().get(0).getGroup());
    assertEquals("Staff", ca.getAccepted().get(1).getGroup().getName());
    assertEquals("Developers", ca.getAutoVerify().getName());
    assertTrue(ca.isRequireContactInformation());

    AccessSection section = cfg.getAccessSection("refs/heads/*");
    assertNotNull("has refs/heads/*", section);
    assertNull("no refs/*", cfg.getAccessSection("refs/*"));

    Permission create = section.getPermission(Permission.CREATE);
    Permission submit = section.getPermission(Permission.SUBMIT);
    Permission read = section.getPermission(Permission.READ);
    Permission push = section.getPermission(Permission.PUSH);

    assertTrue(create.getExclusiveGroup());
    assertTrue(submit.getExclusiveGroup());
    assertTrue(read.getExclusiveGroup());
    assertFalse(push.getExclusiveGroup());
  }

  @Test
  public void testReadConfigLabelDefaultValue() throws Exception {
    RevCommit rev = util.commit(util.tree( //
        util.file("groups", util.blob(group(developers))), //
        util.file("project.config", util.blob(""//
            + "[label \"CustomLabel\"]\n" //
            + "  value = -1 Negative\n" //
            + "  value =  0 No Score\n" //
            + "  value =  1 Positive\n")) //
        ));

    ProjectConfig cfg = read(rev);
    Map<String, LabelType> labels = cfg.getLabelSections();
    Short dv = labels.entrySet().iterator().next().getValue().getDefaultValue();
    assertEquals(0, (int) dv);
  }

  @Test
  public void testReadConfigLabelDefaultValueInRange() throws Exception {
    RevCommit rev = util.commit(util.tree( //
        util.file("groups", util.blob(group(developers))), //
        util.file("project.config", util.blob(""//
            + "[label \"CustomLabel\"]\n" //
            + "  value = -1 Negative\n" //
            + "  value =  0 No Score\n" //
            + "  value =  1 Positive\n" //
            + "  defaultValue = -1\n")) //
        ));

    ProjectConfig cfg = read(rev);
    Map<String, LabelType> labels = cfg.getLabelSections();
    Short dv = labels.entrySet().iterator().next().getValue().getDefaultValue();
    assertEquals(-1, (int) dv);
  }

  @Test
  public void testReadConfigLabelDefaultValueNotInRange() throws Exception {
    RevCommit rev = util.commit(util.tree( //
        util.file("groups", util.blob(group(developers))), //
        util.file("project.config", util.blob(""//
            + "[label \"CustomLabel\"]\n" //
            + "  value = -1 Negative\n" //
            + "  value =  0 No Score\n" //
            + "  value =  1 Positive\n" //
            + "  defaultValue = -2\n")) //
        ));

    ProjectConfig cfg = read(rev);
    assertEquals(1, cfg.getValidationErrors().size());
    assertEquals("project.config: Invalid defaultValue \"-2\" "
        + "for label \"CustomLabel\"",
        Iterables.getOnlyElement(cfg.getValidationErrors()).getMessage());
  }

  @Test
  public void testEditConfig() throws Exception {
    RevCommit rev = util.commit(util.tree( //
        util.file("groups", util.blob(group(developers))), //
        util.file("project.config", util.blob(""//
            + "[access \"refs/heads/*\"]\n" //
            + "  exclusiveGroupPermissions = read submit\n" //
            + "  submit = group Developers\n" //
            + "  upload = group Developers\n" //
            + "  read = group Developers\n" //
            + "[accounts]\n" //
            + "  sameGroupVisibility = deny group Developers\n" //
            + "  sameGroupVisibility = block group Staff\n" //
            + "[contributor-agreement \"Individual\"]\n" //
            + "  description = A simple description\n" //
            + "  accepted = group Developers\n" //
            + "  requireContactInformation = true\n" //
            + "  autoVerify = group Developers\n" //
            + "  agreementUrl = http://www.example.com/agree\n")) //
        ));
    update(rev);

    ProjectConfig cfg = read(rev);
    AccessSection section = cfg.getAccessSection("refs/heads/*");
    cfg.getAccountsSection().setSameGroupVisibility(
        Collections.singletonList(new PermissionRule(cfg.resolve(staff))));
    Permission submit = section.getPermission(Permission.SUBMIT);
    submit.add(new PermissionRule(cfg.resolve(staff)));
    ContributorAgreement ca = cfg.getContributorAgreement("Individual");
    ca.setRequireContactInformation(false);
    ca.setAccepted(Collections.singletonList(new PermissionRule(cfg.resolve(staff))));
    ca.setAutoVerify(null);
    ca.setDescription("A new description");
    rev = commit(cfg);
    assertEquals(""//
        + "[access \"refs/heads/*\"]\n" //
        + "  exclusiveGroupPermissions = read submit\n" //
        + "  submit = group Developers\n" //
        + "\tsubmit = group Staff\n" //
        + "  upload = group Developers\n" //
        + "  read = group Developers\n"//
        + "[accounts]\n" //
        + "  sameGroupVisibility = group Staff\n" //
        + "[contributor-agreement \"Individual\"]\n" //
        + "  description = A new description\n" //
        + "  accepted = group Staff\n" //
        + "  agreementUrl = http://www.example.com/agree\n",
        text(rev, "project.config"));
  }

  @Test
  public void testEditConfigMissingGroupTableEntry() throws Exception {
    RevCommit rev = util.commit(util.tree( //
        util.file("groups", util.blob(group(developers))), //
        util.file("project.config", util.blob(""//
            + "[access \"refs/heads/*\"]\n" //
            + "  exclusiveGroupPermissions = read submit\n" //
            + "  submit = group People Who Can Submit\n" //
            + "  upload = group Developers\n" //
            + "  read = group Developers\n")) //
        ));
    update(rev);

    ProjectConfig cfg = read(rev);
    AccessSection section = cfg.getAccessSection("refs/heads/*");
    Permission submit = section.getPermission(Permission.SUBMIT);
    submit.add(new PermissionRule(cfg.resolve(staff)));
    rev = commit(cfg);
    assertEquals(""//
        + "[access \"refs/heads/*\"]\n" //
        + "  exclusiveGroupPermissions = read submit\n" //
        + "  submit = group People Who Can Submit\n" //
        + "\tsubmit = group Staff\n" //
        + "  upload = group Developers\n" //
        + "  read = group Developers\n", text(rev, "project.config"));
  }

  private ProjectConfig read(RevCommit rev) throws IOException,
      ConfigInvalidException {
    ProjectConfig cfg = new ProjectConfig(new Project.NameKey("test"));
    cfg.load(db, rev);
    return cfg;
  }

  private RevCommit commit(ProjectConfig cfg) throws IOException,
      MissingObjectException, IncorrectObjectTypeException {
    MetaDataUpdate md = new MetaDataUpdate(
        GitReferenceUpdated.DISABLED,
        cfg.getProject().getNameKey(),
        db);
    util.tick(5);
    util.setAuthorAndCommitter(md.getCommitBuilder());
    md.setMessage("Edit\n");
    cfg.commit(md);

    Ref ref = db.getRef(RefNames.REFS_CONFIG);
    return util.getRevWalk().parseCommit(ref.getObjectId());
  }

  private void update(RevCommit rev) throws Exception {
    RefUpdate u = db.updateRef(RefNames.REFS_CONFIG);
    u.disableRefLog();
    u.setNewObjectId(rev);
    switch (u.forceUpdate()) {
      case FAST_FORWARD:
      case FORCED:
      case NEW:
      case NO_CHANGE:
        break;
      default:
        fail("Cannot update ref for test: " + u.getResult());
    }
  }

  private String text(RevCommit rev, String path) throws Exception {
    RevObject blob = util.get(rev.getTree(), path);
    byte[] data = db.open(blob).getCachedBytes(Integer.MAX_VALUE);
    return RawParseUtils.decode(data);
  }

  private static String group(GroupReference g) {
    return g.getUUID().get() + "\t" + g.getName() + "\n";
  }
}
