// 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.zuul.util;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.gerrit.entities.Change;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.server.restapi.change.ChangesCollection;
import com.google.gerrit.server.restapi.change.QueryChanges;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class NeededByFetcherTest {
  private ChangesCollection changes;
  private CommitMessageFetcher commitMessageFetcher;
  private DependsOnExtractor dependsOnExtractor;
  private Change.Key changeKey = getChangeKey(1);

  @Test
  public void testFetchForChangeKeyNoResults() throws Exception {
    List<ChangeInfo> searchResult = new ArrayList<>();

    configureMocks(searchResult);

    NeededByFetcher fetcher = createFetcher();

    List<String> neededBy = fetcher.fetchForChangeKey(changeKey);

    assertThat(neededBy).isEmpty();
  }

  @Test
  public void testFetchForChangeKeySingleResult() throws Exception {
    List<ChangeInfo> searchResult = new ArrayList<>();
    searchResult.add(getChangeInfo(2));

    configureMocks(searchResult);

    NeededByFetcher fetcher = createFetcher();

    List<String> neededBy = fetcher.fetchForChangeKey(changeKey);

    assertThat(neededBy).containsExactly(getChangeKey(2).toString());
  }

  @Test
  public void testFetchForChangeKeySingleResultUnmatchedEmpty() throws Exception {
    List<ChangeInfo> searchResult = new ArrayList<>();
    searchResult.add(getChangeInfo(2));

    configureMocks(searchResult);
    when(dependsOnExtractor.extract("commitMessage2")).thenReturn(new ArrayList<>());

    NeededByFetcher fetcher = createFetcher();

    List<String> neededBy = fetcher.fetchForChangeKey(changeKey);

    assertThat(neededBy).isEmpty();
  }

  @Test
  public void testFetchForChangeKeySingleResultUnmatchedDifferent() throws Exception {
    List<ChangeInfo> searchResult = new ArrayList<>();
    searchResult.add(getChangeInfo(2));

    configureMocks(searchResult);
    List<String> extracted = new ArrayList<>();
    extracted.add(getChangeKey(3).toString());
    when(dependsOnExtractor.extract("commitMessage2")).thenReturn(extracted);

    NeededByFetcher fetcher = createFetcher();

    List<String> neededBy = fetcher.fetchForChangeKey(changeKey);

    assertThat(neededBy).isEmpty();
  }

  @Test
  public void testFetchForChangeKeyMultipleResults() throws Exception {
    List<ChangeInfo> searchResult = new ArrayList<>();
    searchResult.add(getChangeInfo(2));
    searchResult.add(getChangeInfo(3));

    configureMocks(searchResult);

    NeededByFetcher fetcher = createFetcher();

    List<String> neededBy = fetcher.fetchForChangeKey(changeKey);

    assertThat(neededBy).containsExactly(getChangeKey(2).toString(), getChangeKey(3).toString());
  }

  @Test
  public void testFetchForChangeKeyMultipleResultsSomeUnmatched() throws Exception {
    List<ChangeInfo> searchResult = new ArrayList<>();
    searchResult.add(getChangeInfo(2));
    searchResult.add(getChangeInfo(3));
    searchResult.add(getChangeInfo(4));
    searchResult.add(getChangeInfo(5));

    configureMocks(searchResult);
    when(dependsOnExtractor.extract("commitMessage3")).thenReturn(new ArrayList<>());
    when(dependsOnExtractor.extract("commitMessage4")).thenReturn(new ArrayList<>());

    NeededByFetcher fetcher = createFetcher();

    List<String> neededBy = fetcher.fetchForChangeKey(changeKey);

    assertThat(neededBy).containsExactly(getChangeKey(2).toString(), getChangeKey(5).toString());
  }

  /**
   * Sets up mocks for a given search result.
   *
   * <p>Each search result is configured to have a `Depends-On` to the changeKey per default. To
   * refine, override the extraction for ("commitMessage" + number) to the desired list of
   * Change-Ids.
   *
   * @param searchResult The search result to configure.
   * @throws Exception thrown upon issues.
   */
  public void configureMocks(final List<ChangeInfo> searchResult) throws Exception {
    QueryChanges queryChanges = mock(QueryChanges.class);
    final AtomicBoolean addedQuery = new AtomicBoolean(false);
    final AtomicBoolean addedOptionCurrentRevision = new AtomicBoolean(false);
    final AtomicBoolean addedOptionCurrentCommit = new AtomicBoolean(false);

    mockQueryChangesWithSwitch(queryChanges, addedOptionCurrentCommit)
        .addOption(ListChangesOption.CURRENT_COMMIT);
    mockQueryChangesWithSwitch(queryChanges, addedOptionCurrentRevision)
        .addOption(ListChangesOption.CURRENT_REVISION);
    mockQueryChangesWithSwitch(queryChanges, addedQuery)
        .addQuery("message:" + changeKey + " -change:" + changeKey);
    when(queryChanges.apply(TopLevelResource.INSTANCE))
        .thenAnswer(
            new Answer<Response<List<ChangeInfo>>>() {

              @Override
              public Response<List<ChangeInfo>> answer(InvocationOnMock invocation)
                  throws Throwable {
                boolean ready =
                    addedOptionCurrentRevision.get()
                        && addedOptionCurrentCommit.get()
                        && addedQuery.get();
                if (!ready) {
                  fail("executed query before all options were set");
                }
                return Response.ok(searchResult);
              }
            });

    changes = mock(ChangesCollection.class);
    when(changes.list()).thenReturn(queryChanges);

    commitMessageFetcher = mock(CommitMessageFetcher.class);
    when(commitMessageFetcher.fetch(any(ChangeInfo.class)))
        .thenAnswer(
            new Answer<String>() {
              @Override
              public String answer(InvocationOnMock invocation) throws Throwable {
                ChangeInfo changeInfo = invocation.getArgument(0);
                return "commitMessage" + changeInfo._number;
              }
            });

    dependsOnExtractor = mock(DependsOnExtractor.class);
    List<String> extractedMatchList = new ArrayList<>();
    extractedMatchList.add(changeKey.toString());
    when(dependsOnExtractor.extract(any(String.class))).thenReturn(extractedMatchList);
  }

  private QueryChanges mockQueryChangesWithSwitch(
      QueryChanges queryChanges, AtomicBoolean booleanSwitch) {
    return doAnswer(
            new Answer<Void>() {
              @Override
              public Void answer(InvocationOnMock invocation) throws Throwable {
                if (booleanSwitch.getAndSet(true)) {
                  fail("flag has already been set");
                }
                return null;
              }
            })
        .when(queryChanges);
  }

  private Change.Key getChangeKey(int keyEnding) {
    return Change.key("I0123456789abcdef0000000000000000000" + (10000 + keyEnding));
  }

  private ChangeInfo getChangeInfo(int keyEnding) {
    ChangeInfo changeInfo = new ChangeInfo();
    changeInfo.changeId = getChangeKey(keyEnding).toString();
    changeInfo._number = keyEnding;
    return changeInfo;
  }

  private NeededByFetcher createFetcher() {
    return new NeededByFetcher(changes, commitMessageFetcher, dependsOnExtractor);
  }
}
