// Copyright (C) 2017 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.findowners;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.entities.RefNames.REFS_CONFIG;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.api.projects.BranchApi;
import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeInput;
import com.google.gerrit.server.account.Emails;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.junit.Before;

/** Abstract base class for find-owners plugin integration tests. */
public abstract class FindOwners extends LightweightPluginDaemonTest {

  @Inject protected Emails emails;
  @Inject protected PermissionBackend permissionBackend;
  @Inject protected ProjectOperations projectOperations;
  @Inject protected PatchListCache patchListCache;

  protected static final String PLUGIN_NAME = "find-owners";
  protected Config config;

  @Before
  public void setConfig() {
    config = new Config(pluginConfig, null, null, null, null);
  }

  protected String oneOwnerList(String email) {
    return "owners:[" + ownerJson(email) + "]";
  }

  protected String ownerJson(String email) {
    return "{email:" + email + ",weights:[1,0,0]}";
  }

  protected String ownerJson(String email, int w1, int w2, int w3) {
    return "{email:" + email + ",weights:[" + w1 + "," + w2 + "," + w3 + "]}";
  }

  protected ChangeInfo newChangeInfo(String subject) throws Exception {
    ChangeInput in = new ChangeInput();
    in.project = project.get();
    in.branch = "master";
    in.subject = subject;
    in.topic = "";
    in.status = ChangeStatus.NEW;
    return gApi.changes().create(in).get();
  }

  protected String getFindOwnersResponse(ChangeInfo info) throws Exception {
    return filteredJson(
        userRestSession.get("/changes/" + info._number + "/revisions/1/" + PLUGIN_NAME));
  }

  protected String getOwnersResponse(ChangeInfo info) throws Exception {
    return filteredJson(userRestSession.get("/changes/" + info._number + "/owners"));
  }

  protected String getOwnersResponse(PushOneCommit.Result change) throws Exception {
    return filteredJson(userRestSession.get("/changes/" + change.getChangeId() + "/owners"));
  }

  protected String getOwnersDebugResponse(PushOneCommit.Result change) throws Exception {
    return filteredJson(
        userRestSession.get("/changes/" + change.getChangeId() + "/owners?debug=1"));
  }

  protected void approveSubmit(PushOneCommit.Result change) throws Exception {
    approve(change.getChangeId());
    gApi.changes().id(change.getChangeId()).current().submit(new SubmitInput());
  }

  protected PushOneCommit.Result addFile(String subject, String file, String content)
      throws Exception {
    PushOneCommit.Result c = createChange(subject, file, content);
    approveSubmit(c);
    return c;
  }

  protected void switchProject(Project.NameKey p) throws Exception {
    project = p;
    testRepo = cloneProject(project);
  }

  protected void blockRead(Project.NameKey p) throws Exception {
    projectOperations
        .project(p)
        .forUpdate()
        .add(block(Permission.READ).ref("refs/heads/master").group(REGISTERED_USERS))
        .update();
  }

  protected org.eclipse.jgit.lib.Config readProjectConfig() throws Exception {
    git().fetch().setRefSpecs(new RefSpec(REFS_CONFIG + ":" + REFS_CONFIG)).call();
    testRepo.reset(RefNames.REFS_CONFIG);
    RevWalk rw = testRepo.getRevWalk();
    RevTree tree = rw.parseTree(testRepo.getRepository().resolve("HEAD"));

    try (TreeWalk treeWalk = new TreeWalk(rw.getObjectReader())) {
      treeWalk.setFilter(PathFilterGroup.createFromStrings("project.config"));
      treeWalk.reset(tree);
      boolean hasProjectConfig = treeWalk.next();
      if (!hasProjectConfig) {
        return new org.eclipse.jgit.lib.Config();
      }
    }

    RevObject obj = rw.parseAny(testRepo.get(tree, "project.config"));
    ObjectLoader loader = rw.getObjectReader().open(obj);
    String text = new String(loader.getCachedBytes(), UTF_8);
    org.eclipse.jgit.lib.Config cfg = new org.eclipse.jgit.lib.Config();
    cfg.fromText(text);
    return cfg;
  }

  protected void setProjectConfig(String var, String value) throws Exception {
    org.eclipse.jgit.lib.Config cfg = readProjectConfig();
    cfg.setString("plugin", PLUGIN_NAME, var, value);
    assertThat(cfg.getString("plugin", PLUGIN_NAME, var)).isEqualTo(value);
    PushOneCommit.Result commit =
        pushFactory
            .create(
                admin.newIdent(), // normal user cannot change refs/meta/config
                testRepo,
                "Update project config",
                "project.config",
                cfg.toText())
            .to("refs/for/" + REFS_CONFIG);
    commit.assertOkStatus();
    approveSubmit(commit);
    testRepo = cloneProject(project); // reset the testRepo after cfg change
  }

  protected int checkApproval(PushOneCommit.Result r) throws Exception {
    Project.NameKey project = r.getChange().project();
    Cache cache = getCache().init(0, 0);
    OwnersDb db =
        cache.get(
            true,
            null,
            projectCache.get(project),
            accountCache,
            emails,
            repoManager,
            r.getChange(),
            1);
    Checker c =
        new Checker(
            accountCache,
            patchListCache,
            repoManager,
            emails,
            pluginConfig,
            null,
            r.getChange(),
            1);
    return c.findApproval(db);
  }

  // To simplify test case code, the REST API returned JSON string is filtered to
  // remove '\t', ' ' and '"', but replace "\\\"" with '"',
  // replace '\n' with space, remove "owner_revision:*" and "HostName:*",
  // and replace some unicode with simple characters.
  protected static String filteredJson(String json) {
    return json.replaceAll("[\t ]", "")
        .replace("\\\"", "\t")
        .replace("\"", "")
        .replace('\t', '"')
        .replace('\n', ' ')
        .replaceAll("owner_revision:[^ ]* ", "")
        .replaceAll("HostName:[^ ]*, ", "")
        .replace("\\u0027", "'")
        .replace("\\u003d", "=")
        .replace("\\u003e", ">");
  }

  protected static String filteredJson(RestResponse response) throws Exception {
    return filteredJson(response.getEntityContent());
  }

  protected String myProjectName(String test, String project) {
    return this.getClass().getName() + "_" + test + "_" + project;
  }

  protected String idProject(String test, String project) {
    return idProject(myProjectName(test, project));
  }

  protected String idProject(String name) {
    // Expected string of "id": "name",,
    return "\"id\":\"" + name + "\",";
  }

  protected static void verifyRestResult(
      RestResult result, int voteLevel, int patchset, int changeNumber, boolean addDebugMsg)
      throws Exception {
    assertThat(result.minOwnerVoteLevel).isEqualTo(voteLevel);
    assertThat(result.patchset).isEqualTo(patchset);
    assertThat(result.change).isEqualTo(changeNumber);
    assertThat(result.addDebugMsg).isEqualTo(addDebugMsg);
    if (addDebugMsg) {
      assertThat(result.dbgmsgs).isNotNull();
    } else {
      assertThat(result.dbgmsgs).isNull();
    }
  }

  protected BranchApi createBranch(String branch) throws Exception {
    return createBranch(BranchNameKey.create(project, branch));
  }

  protected PushOneCommit.Result createChangeInBranch(
      String branch, String subject, String fileName, String content) throws Exception {
    PushOneCommit push = pushFactory.create(admin.newIdent(), testRepo, subject, fileName, content);
    return push.to("refs/for/" + branch);
  }

  protected Project.NameKey newProject(String name) {
    return newProject(name, Project.nameKey("All-Projects"));
  }

  protected Project.NameKey newProject(String name, Project.NameKey parent) {
    return projectOperations.newProject().parent(parent).name(name).create();
  }

  protected String projectOwnersFileName(Project.NameKey name) {
    // This function is called repeatedly in ConfigIT without recreating config.
    // So, here we recreate config, to get the latest owners file name.
    setConfig();
    return config.getOwnersFileName(projectCache.get(name), null);
  }

  protected Cache getCache() {
    return Cache.getInstance(config, repoManager);
  }
}
