// Copyright (C) 2021 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.notedb;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.ImmutableSet;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.entities.Account;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.annotations.Exports;
import com.google.gerrit.server.ServerInitiated;
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIdFactory;
import com.google.gerrit.server.account.externalids.ExternalIdNotes;
import com.google.gerrit.server.account.externalids.ExternalIdUpsertPreprocessor;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.notedb.Sequences;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;

/** Tests {@link ExternalIdUpsertPreprocessor}. */
@TestPlugin(
    name = "external-id-update-preprocessor",
    sysModule =
        "com.google.gerrit.acceptance.server.notedb.ExternalIdNotesUpsertPreprocessorIT$Module")
public class ExternalIdNotesUpsertPreprocessorIT extends LightweightPluginDaemonTest {
  @Inject private Sequences sequences;
  @Inject private @ServerInitiated Provider<AccountsUpdate> accountsUpdateProvider;
  @Inject private ExternalIdNotes.Factory extIdNotesFactory;
  @Inject private ExternalIdFactory extIdFactory;

  public static class Module extends AbstractModule {
    @Override
    protected void configure() {
      bind(ExternalIdUpsertPreprocessor.class)
          .annotatedWith(Exports.named("TestPreprocessor"))
          .to(TestPreprocessor.class);
    }
  }

  private TestPreprocessor testPreprocessor;

  @Before
  public void setUp() {
    testPreprocessor = plugin.getSysInjector().getInstance(TestPreprocessor.class);
    testPreprocessor.reset();
  }

  @Test
  public void insertAccount() throws Exception {
    Account.Id id = Account.id(sequences.nextAccountId());
    ExternalId extId = extIdFactory.create("foo", "bar", id);
    accountsUpdateProvider.get().insert("test", id, u -> u.addExternalId(extId));
    assertThat(testPreprocessor.upserted).containsExactly(extId);
  }

  @Test
  public void replaceByKeys() throws Exception {
    Account.Id id = Account.id(sequences.nextAccountId());
    ExternalId extId1 = extIdFactory.create("foo", "bar1", id);
    ExternalId extId2 = extIdFactory.create("foo", "bar2", id);
    accountsUpdateProvider.get().insert("test", id, u -> u.addExternalId(extId1));

    testPreprocessor.reset();
    try (Repository allUsersRepo = repoManager.openRepository(allUsers);
        MetaDataUpdate md = metaDataUpdateFactory.create(allUsers)) {
      ExternalIdNotes extIdNotes = extIdNotesFactory.load(allUsersRepo);
      extIdNotes.replaceByKeys(ImmutableSet.of(extId1.key()), ImmutableSet.of(extId2));
      extIdNotes.commit(md);
    }
    assertThat(testPreprocessor.upserted).containsExactly(extId2);
  }

  @Test
  public void insert() throws Exception {
    Account.Id id = Account.id(sequences.nextAccountId());
    ExternalId extId = extIdFactory.create("foo", "bar", id);

    try (Repository allUsersRepo = repoManager.openRepository(allUsers);
        MetaDataUpdate md = metaDataUpdateFactory.create(allUsers)) {
      ExternalIdNotes extIdNotes = extIdNotesFactory.load(allUsersRepo);
      extIdNotes.insert(extId);
      extIdNotes.commit(md);
    }
    assertThat(testPreprocessor.upserted).containsExactly(extId);
  }

  @Test
  public void upsert() throws Exception {
    Account.Id id = Account.id(sequences.nextAccountId());
    ExternalId extId = extIdFactory.create("foo", "bar", id);

    try (Repository allUsersRepo = repoManager.openRepository(allUsers);
        MetaDataUpdate md = metaDataUpdateFactory.create(allUsers)) {
      ExternalIdNotes extIdNotes = extIdNotesFactory.load(allUsersRepo);
      extIdNotes.upsert(extId);
      extIdNotes.commit(md);
    }
    assertThat(testPreprocessor.upserted).containsExactly(extId);
  }

  @Test
  public void replace() throws Exception {
    Account.Id id = Account.id(sequences.nextAccountId());
    ExternalId extId1 = extIdFactory.create("foo", "bar1", id);
    ExternalId extId2 = extIdFactory.create("foo", "bar2", id);
    accountsUpdateProvider.get().insert("test", id, u -> u.addExternalId(extId1));

    testPreprocessor.reset();
    try (Repository allUsersRepo = repoManager.openRepository(allUsers);
        MetaDataUpdate md = metaDataUpdateFactory.create(allUsers)) {
      ExternalIdNotes extIdNotes = extIdNotesFactory.load(allUsersRepo);
      extIdNotes.replace(ImmutableSet.of(extId1), ImmutableSet.of(extId2));
      extIdNotes.commit(md);
    }
    assertThat(testPreprocessor.upserted).containsExactly(extId2);
  }

  @Test
  public void replace_viaAccountsUpdate() throws Exception {
    Account.Id id = Account.id(sequences.nextAccountId());
    ExternalId extId1 = extIdFactory.create("foo", "bar", id, "email1@foo", "hash");
    ExternalId extId2 = extIdFactory.create("foo", "bar", id, "email2@foo", "hash");
    accountsUpdateProvider.get().insert("test", id, u -> u.addExternalId(extId1));

    testPreprocessor.reset();
    accountsUpdateProvider.get().update("test", id, u -> u.updateExternalId(extId2));
    assertThat(testPreprocessor.upserted).containsExactly(extId2);
  }

  @Test
  public void blockUpsert() throws Exception {
    Account.Id id = Account.id(sequences.nextAccountId());
    ExternalId extId = extIdFactory.create("foo", "bar", id);
    testPreprocessor.throwException = true;
    StorageException e =
        assertThrows(
            StorageException.class,
            () -> accountsUpdateProvider.get().insert("test", id, u -> u.addExternalId(extId)));
    assertThat(e).hasMessageThat().contains("upsert not good");
    assertThat(testPreprocessor.upserted).isEmpty();
  }

  @Test
  public void blockUpsert_replace() throws Exception {
    Account.Id id = Account.id(sequences.nextAccountId());
    ExternalId extId1 = extIdFactory.create("foo", "bar", id, "email1@foo", "hash");
    ExternalId extId2 = extIdFactory.create("foo", "bar", id, "email2@foo", "hash");
    accountsUpdateProvider.get().insert("test", id, u -> u.addExternalId(extId1));

    assertThat(accounts.get(id).get().externalIds()).containsExactly(extId1);

    testPreprocessor.reset();
    testPreprocessor.throwException = true;
    try (Repository allUsersRepo = repoManager.openRepository(allUsers);
        MetaDataUpdate md = metaDataUpdateFactory.create(allUsers)) {
      ExternalIdNotes extIdNotes = extIdNotesFactory.load(allUsersRepo);
      extIdNotes.replace(ImmutableSet.of(extId1), ImmutableSet.of(extId2));
      StorageException e = assertThrows(StorageException.class, () -> extIdNotes.commit(md));
      assertThat(e).hasMessageThat().contains("upsert not good");
    }
    assertThat(testPreprocessor.upserted).isEmpty();
    assertThat(accounts.get(id).get().externalIds()).containsExactly(extId1);
  }

  @Singleton
  public static class TestPreprocessor implements ExternalIdUpsertPreprocessor {
    List<ExternalId> upserted = new ArrayList<>();

    boolean throwException = false;

    @Override
    public void upsert(ExternalId extId) {
      assertThat(extId.blobId()).isNotNull();
      if (throwException) {
        throw new StorageException("upsert not good");
      }
      upserted.add(extId);
    }

    void reset() {
      upserted.clear();
      throwException = false;
    }
  }
}
