// Copyright (C) 2020 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.reviewers;

import static com.google.gerrit.acceptance.GitUtil.fetch;
import static com.googlesource.gerrit.plugins.reviewers.config.ReviewersConfig.FILENAME;
import static com.googlesource.gerrit.plugins.reviewers.config.ReviewersConfig.KEY_CC;
import static com.googlesource.gerrit.plugins.reviewers.config.ReviewersConfig.KEY_REVIEWER;
import static com.googlesource.gerrit.plugins.reviewers.config.ReviewersConfig.SECTION_FILTER;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.entities.RefNames;
import com.google.inject.Inject;
import java.util.Arrays;
import java.util.Set;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.junit.Ignore;

/** Base class for reviewer plugin tests. */
@Ignore
public class AbstractReviewersPluginTest extends LightweightPluginDaemonTest {
  @Inject protected ProjectOperations projectOperations;

  protected void createFilters(TestFilter... filters) throws Exception {
    createFiltersFor(testRepo, filters);
  }

  protected void createFiltersFor(TestRepository<?> repo, TestFilter... filters) throws Exception {
    String previousHead = repo.getRepository().getBranch();
    checkoutRefsMetaConfig(repo);
    Config cfg = new Config();
    Arrays.stream(filters)
        .forEach(
            f -> {
              cfg.setStringList(
                  SECTION_FILTER, f.filter, KEY_REVIEWER, Lists.newArrayList(f.reviewers));
              cfg.setStringList(SECTION_FILTER, f.filter, KEY_CC, Lists.newArrayList(f.ccs));
            });
    pushFactory
        .create(admin.newIdent(), repo, "Add reviewers", FILENAME, cfg.toText())
        .to(RefNames.REFS_CONFIG)
        .assertOkStatus();
    repo.reset(previousHead);
  }

  protected TestRepository<?> checkoutRefsMetaConfig(TestRepository<?> repo) throws Exception {
    fetch(repo, RefNames.REFS_CONFIG + ":refs/heads/config");
    repo.reset("refs/heads/config");
    return repo;
  }

  private TestFilter filter(String filter, Set<String> reviewers, Set<String> ccs) {
    return new TestFilter(filter, reviewers, ccs);
  }

  protected TestFilter filter(String filter) {
    return new TestFilter(filter);
  }

  protected static class TestFilter extends ReviewerFilter {

    public TestFilter(String filter, Set<String> reviewers, Set<String> ccs) {
      this.filter = filter;
      this.reviewers = reviewers;
      this.ccs = ccs;
    }

    public TestFilter(String filter) {
      this(filter, Sets.newHashSet(), Sets.newHashSet());
    }

    public TestFilter reviewer(String reviewerId) {
      reviewers.add(reviewerId);
      return this;
    }

    public TestFilter reviewer(TestAccount reviewer) {
      return reviewer(reviewer.email());
    }

    public TestFilter cc(String ccId) {
      ccs.add(ccId);
      return this;
    }

    public TestFilter cc(TestAccount cc) {
      return cc(cc.email());
    }
  }
}
