// 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.server.notedb;

import static com.google.gerrit.testing.TestActionRefUpdateContext.testRefAction;
import static com.google.inject.Scopes.SINGLETON;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.mockito.Mockito.mock;

import com.google.common.collect.ImmutableList;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.CommentRange;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.SubmitRecord;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.metrics.DisabledMetricMaker;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.server.ChangeDraftUpdate;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.DefaultRefLogIdentityProvider;
import com.google.gerrit.server.FanOutExecutor;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.InternalUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.FakeRealm;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.Realm;
import com.google.gerrit.server.account.ServiceUserClassifier;
import com.google.gerrit.server.account.externalids.ExternalIdCache;
import com.google.gerrit.server.account.externalids.storage.notedb.DisabledExternalIdCache;
import com.google.gerrit.server.approval.PatchSetApprovalUuidGenerator;
import com.google.gerrit.server.approval.testing.TestPatchSetApprovalUuidGenerator;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.gerrit.server.config.AnonymousCowardName;
import com.google.gerrit.server.config.AnonymousCowardNameProvider;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.DefaultUrlFormatter.DefaultUrlFormatterModule;
import com.google.gerrit.server.config.EnablePeerIPInReflogRecord;
import com.google.gerrit.server.config.GerritImportedServerIds;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.GerritServerId;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitModule;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.RepositoryCaseMismatchException;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.project.NullProjectCache;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.testing.AssertableExecutorService;
import com.google.gerrit.testing.ConfigSuite;
import com.google.gerrit.testing.FakeAccountCache;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import com.google.gerrit.testing.TestChanges;
import com.google.gerrit.testing.TestTimeUtil;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.runner.RunWith;

@Ignore
@RunWith(ConfigSuite.class)
public abstract class AbstractChangeNotesTest {
  protected static final String LOCAL_SERVER_ID = "gerrit";
  protected static final String FQ_USER_IDENT =
      "Gerrit User 1000000 \\u003c1000000@" + LOCAL_SERVER_ID;

  private static final ZoneId ZONE_ID = ZoneId.of("America/Los_Angeles");

  @ConfigSuite.Parameter public Config testConfig;

  protected Account.Id changeOwnerId;
  protected Account.Id otherUserId;
  protected FakeAccountCache accountCache;
  protected IdentifiedUser changeOwner;
  protected IdentifiedUser otherUser;
  protected InMemoryRepository repo;
  protected InMemoryRepositoryManager repoManager;
  protected PersonIdent serverIdent;
  protected InternalUser internalUser;
  protected Project.NameKey project;
  protected RevWalk rw;
  protected TestRepository<InMemoryRepository> tr;
  protected AssertableExecutorService assertableFanOutExecutor;
  protected GitReferenceUpdated gitReferenceUpdated;

  @Inject protected IdentifiedUser.GenericFactory userFactory;

  @Inject protected NoteDbUpdateManager.Factory updateManagerFactory;

  @Inject protected AllUsersName allUsers;

  @Inject protected AbstractChangeNotes.Args args;

  @Inject @GerritServerId protected String serverId;

  @Inject protected ExternalIdCache externalIdCache;

  protected Injector injector;
  private String systemTimeZone;

  @Inject protected ChangeNotes.Factory changeNotesFactory;

  @Before
  public void setUpTestEnvironment() throws Exception {
    setupTestPrerequisites();

    injector = createTestInjector(LOCAL_SERVER_ID);
    createAllUsers(injector);
    injector.injectMembers(this);
  }

  protected void setupTestPrerequisites() throws Exception {
    setTimeForTesting();

    serverIdent = new PersonIdent("Gerrit Server", "noreply@gerrit.com", TimeUtil.now(), ZONE_ID);
    project = Project.nameKey("test-project");
    repoManager = new InMemoryRepositoryManager();
    repo = repoManager.createRepository(project);
    tr = new TestRepository<>(repo);
    rw = tr.getRevWalk();
    accountCache = new FakeAccountCache();
    Account.Builder co = Account.builder(Account.id(1), TimeUtil.now());
    co.setFullName("Change Owner");
    co.setPreferredEmail("change@owner.com");
    accountCache.put(co.build());
    Account.Builder ou = Account.builder(Account.id(2), TimeUtil.now());
    ou.setFullName("Other Account");
    ou.setPreferredEmail("other@account.com");
    accountCache.put(ou.build());
    assertableFanOutExecutor = new AssertableExecutorService();
    gitReferenceUpdated = mock(GitReferenceUpdated.class);
    changeOwnerId = co.id();
    otherUserId = ou.id();
    internalUser = new InternalUser();
  }

  protected Injector createTestInjector(String serverId, String... importedServerIds)
      throws Exception {
    return createTestInjector(DisabledExternalIdCache.module(), serverId, importedServerIds);
  }

  protected Injector createTestInjector(
      Module extraGuiceModule, String serverId, String... importedServerIds) throws Exception {

    return Guice.createInjector(
        new FactoryModule() {
          @Override
          public void configure() {
            install(extraGuiceModule);
            install(new GitModule());

            install(new DefaultUrlFormatterModule());
            install(NoteDbModule.forTest());
            install(new DefaultRefLogIdentityProvider.Module());
            bind(AllUsersName.class).toProvider(AllUsersNameProvider.class);
            bind(String.class).annotatedWith(GerritServerId.class).toInstance(serverId);
            bind(new TypeLiteral<ImmutableList<String>>() {})
                .annotatedWith(GerritImportedServerIds.class)
                .toInstance(new ImmutableList.Builder<String>().add(importedServerIds).build());
            bind(GitRepositoryManager.class).toInstance(repoManager);
            bind(ProjectCache.class).to(NullProjectCache.class);
            bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(testConfig);
            bind(String.class)
                .annotatedWith(AnonymousCowardName.class)
                .toProvider(AnonymousCowardNameProvider.class);
            bind(String.class)
                .annotatedWith(CanonicalWebUrl.class)
                .toInstance("http://localhost:8080/");
            bind(Boolean.class)
                .annotatedWith(EnablePeerIPInReflogRecord.class)
                .toInstance(Boolean.FALSE);
            bind(Realm.class).to(FakeRealm.class);
            bind(GroupBackend.class).to(SystemGroupBackend.class).in(SINGLETON);
            bind(AccountCache.class).toInstance(accountCache);
            bind(PersonIdent.class).annotatedWith(GerritPersonIdent.class).toInstance(serverIdent);
            bind(GitReferenceUpdated.class).toInstance(gitReferenceUpdated);
            bind(MetricMaker.class).to(DisabledMetricMaker.class);
            bind(ExecutorService.class)
                .annotatedWith(FanOutExecutor.class)
                .toInstance(assertableFanOutExecutor);
            bind(ServiceUserClassifier.class).to(ServiceUserClassifier.NoOp.class);
            bind(InternalChangeQuery.class)
                .toProvider(
                    () -> {
                      throw new UnsupportedOperationException();
                    });
            bind(PatchSetApprovalUuidGenerator.class).to(TestPatchSetApprovalUuidGenerator.class);
            bind(ChangeDraftUpdate.ChangeDraftUpdateFactory.class)
                .to(ChangeDraftNotesUpdate.Factory.class);
          }
        });
  }

  protected void createAllUsers(Injector injector)
      throws RepositoryCaseMismatchException, RepositoryNotFoundException {
    AllUsersName allUsersName = injector.getInstance(AllUsersName.class);

    repoManager.createRepository(allUsersName);

    IdentifiedUser.GenericFactory identifiedUserFactory =
        injector.getInstance(IdentifiedUser.GenericFactory.class);
    changeOwner = identifiedUserFactory.create(changeOwnerId);
    otherUser = identifiedUserFactory.create(otherUserId);
  }

  private void setTimeForTesting() {
    systemTimeZone = System.setProperty("user.timezone", "US/Eastern");
    TestTimeUtil.resetWithClockStep(1, SECONDS);
  }

  @After
  public void resetTime() {
    TestTimeUtil.useSystemTime();
    System.setProperty("user.timezone", systemTimeZone);
  }

  protected Change newChange(boolean workInProgress) throws Exception {
    return newChange(injector, workInProgress);
  }

  protected Change newChange(Injector injector, boolean workInProgress) throws Exception {
    return testRefAction(
        () -> {
          Change c = TestChanges.newChange(project, changeOwner.getAccountId());
          ChangeUpdate u = newUpdate(injector, c, changeOwner, false);
          u.setChangeId(c.getKey().get());
          u.setBranch(c.getDest().branch());
          u.setWorkInProgress(workInProgress);
          u.commit();
          return c;
        });
  }

  protected Change newWorkInProgressChange() throws Exception {
    return newChange(true);
  }

  protected Change newChange() throws Exception {
    return newChange(false);
  }

  protected ChangeUpdate newUpdateForNewChange(Change c, CurrentUser user) throws Exception {
    return newUpdate(injector, c, user, false);
  }

  protected ChangeUpdate newUpdate(Change c, CurrentUser user) throws Exception {
    return newUpdate(injector, c, user, true);
  }

  protected ChangeUpdate newUpdate(Change c, CurrentUser user, boolean shouldExist)
      throws Exception {
    return newUpdate(injector, c, user, shouldExist);
  }

  protected ChangeUpdate newUpdate(
      Injector injector, Change c, CurrentUser user, boolean shouldExist) throws Exception {
    ChangeUpdate update = TestChanges.newUpdate(injector, c, Optional.of(user), shouldExist);
    update.setPatchSetId(c.currentPatchSetId());
    update.setAllowWriteToNewRef(true);
    return update;
  }

  protected ChangeNotes newNotes(Change c) {
    return new ChangeNotes(args, c, true, null).load();
  }

  protected ChangeNotes newNotes(AbstractChangeNotes.Args cArgs, Change c) {
    return new ChangeNotes(cArgs, c, true, null).load();
  }

  protected static SubmitRecord submitRecord(
      String status, String errorMessage, SubmitRecord.Label... labels) {
    SubmitRecord rec = new SubmitRecord();
    rec.status = SubmitRecord.Status.valueOf(status);
    rec.errorMessage = errorMessage;
    if (labels.length > 0) {
      rec.labels = ImmutableList.copyOf(labels);
    }
    return rec;
  }

  protected static SubmitRecord.Label submitLabel(
      String name, String status, Account.Id appliedBy) {
    SubmitRecord.Label label = new SubmitRecord.Label();
    label.label = name;
    label.status = SubmitRecord.Label.Status.valueOf(status);
    label.appliedBy = appliedBy;
    return label;
  }

  protected HumanComment newComment(
      PatchSet.Id psId,
      String filename,
      String UUID,
      CommentRange range,
      int line,
      IdentifiedUser commenter,
      String parentUUID,
      Instant t,
      String message,
      short side,
      ObjectId commitId,
      boolean unresolved,
      String serverId) {
    HumanComment c =
        new HumanComment(
            new Comment.Key(UUID, filename, psId.get()),
            commenter.getAccountId(),
            t,
            side,
            message,
            serverId,
            unresolved);
    c.lineNbr = line;
    c.parentUuid = parentUUID;
    c.setCommitId(commitId);
    c.setRange(range);
    return c;
  }

  protected HumanComment newComment(
      PatchSet.Id psId,
      String filename,
      String UUID,
      CommentRange range,
      int line,
      IdentifiedUser commenter,
      String parentUUID,
      Instant t,
      String message,
      short side,
      ObjectId commitId,
      boolean unresolved) {
    return newComment(
        psId,
        filename,
        UUID,
        range,
        line,
        commenter,
        parentUUID,
        t,
        message,
        side,
        commitId,
        unresolved,
        serverId);
  }

  protected static Instant truncate(Instant ts) {
    return Instant.ofEpochMilli((ts.toEpochMilli() / 1000) * 1000);
  }

  protected static Instant after(Change c, long millis) {
    return Instant.ofEpochMilli(c.getCreatedOn().toEpochMilli() + millis);
  }
}
