// Copyright (C) 2016 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;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.data.RefUpdateAttribute;
import com.google.gerrit.server.events.ChangeDeletedEvent;
import com.google.gerrit.server.events.ChangeMergedEvent;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.RefEvent;
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.gerrit.server.events.ReviewerDeletedEvent;
import com.google.gerrit.server.events.UserScopedEventListener;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;

public class EventRecorder {
  private final RegistrationHandle eventListenerRegistration;
  private final ListMultimap<String, RefEvent> recordedEvents;

  @Singleton
  public static class Factory {
    private final DynamicSet<UserScopedEventListener> eventListeners;
    private final IdentifiedUser.GenericFactory userFactory;

    @Inject
    Factory(
        DynamicSet<UserScopedEventListener> eventListeners,
        IdentifiedUser.GenericFactory userFactory) {
      this.eventListeners = eventListeners;
      this.userFactory = userFactory;
    }

    public EventRecorder create(TestAccount user) {
      return new EventRecorder(eventListeners, userFactory.create(user.id()));
    }
  }

  public EventRecorder(DynamicSet<UserScopedEventListener> eventListeners, IdentifiedUser user) {
    recordedEvents = LinkedListMultimap.create();

    eventListenerRegistration =
        eventListeners.add(
            "gerrit",
            new UserScopedEventListener() {
              @Override
              public void onEvent(Event e) {
                if (e instanceof ReviewerDeletedEvent) {
                  recordedEvents.put(ReviewerDeletedEvent.TYPE, (ReviewerDeletedEvent) e);
                } else if (e instanceof ChangeDeletedEvent) {
                  recordedEvents.put(ChangeDeletedEvent.TYPE, (ChangeDeletedEvent) e);
                } else if (e instanceof RefEvent) {
                  RefEvent event = (RefEvent) e;
                  String key =
                      refEventKey(
                          event.getType(), event.getProjectNameKey().get(), event.getRefName());
                  recordedEvents.put(key, event);
                }
              }

              @Override
              public CurrentUser getUser() {
                return user;
              }
            });
  }

  private static String refEventKey(String type, String project, String ref) {
    return String.format("%s-%s-%s", type, project, ref);
  }

  private ImmutableList<RefUpdatedEvent> getRefUpdatedEvents(
      String project, String refName, int expectedSize) {
    String key = refEventKey(RefUpdatedEvent.TYPE, project, refName);
    if (expectedSize == 0) {
      assertThat(recordedEvents).doesNotContainKey(key);
      return ImmutableList.of();
    }

    assertThat(recordedEvents).containsKey(key);
    ImmutableList<RefUpdatedEvent> events =
        FluentIterable.from(recordedEvents.get(key))
            .transform(RefUpdatedEvent.class::cast)
            .toList();
    assertThat(events).hasSize(expectedSize);
    return events;
  }

  @VisibleForTesting
  public ImmutableList<ChangeMergedEvent> getChangeMergedEvents(
      String project, String branch, int expectedSize) {
    String key = refEventKey(ChangeMergedEvent.TYPE, project, branch);
    if (expectedSize == 0) {
      assertThat(recordedEvents).doesNotContainKey(key);
      return ImmutableList.of();
    }

    assertThat(recordedEvents).containsKey(key);
    ImmutableList<ChangeMergedEvent> events =
        FluentIterable.from(recordedEvents.get(key))
            .transform(ChangeMergedEvent.class::cast)
            .toList();
    assertThat(events).hasSize(expectedSize);
    return events;
  }

  private ImmutableList<ReviewerDeletedEvent> getReviewerDeletedEvents(int expectedSize) {
    String key = ReviewerDeletedEvent.TYPE;
    if (expectedSize == 0) {
      assertThat(recordedEvents).doesNotContainKey(key);
      return ImmutableList.of();
    }
    assertThat(recordedEvents).containsKey(key);
    ImmutableList<ReviewerDeletedEvent> events =
        FluentIterable.from(recordedEvents.get(key))
            .transform(ReviewerDeletedEvent.class::cast)
            .toList();
    assertThat(events).hasSize(expectedSize);
    return events;
  }

  private ImmutableList<ChangeDeletedEvent> getChangeDeletedEvents(int expectedSize) {
    String key = ChangeDeletedEvent.TYPE;
    if (expectedSize == 0) {
      assertThat(recordedEvents).doesNotContainKey(key);
      return ImmutableList.of();
    }
    assertThat(recordedEvents).containsKey(key);
    ImmutableList<ChangeDeletedEvent> events =
        FluentIterable.from(recordedEvents.get(key))
            .transform(ChangeDeletedEvent.class::cast)
            .toList();
    assertThat(events).hasSize(expectedSize);
    return events;
  }

  public void assertNoRefUpdatedEvents(String project, String branch) throws Exception {
    getRefUpdatedEvents(project, branch, 0);
  }

  public void assertRefUpdatedEvents(String project, String branch, String... expected)
      throws Exception {
    ImmutableList<RefUpdatedEvent> events =
        getRefUpdatedEvents(project, branch, expected.length / 2);
    int i = 0;
    for (RefUpdatedEvent event : events) {
      RefUpdateAttribute actual = event.refUpdate.get();
      String oldRev = expected[i] == null ? ObjectId.zeroId().name() : expected[i];
      String newRev = expected[i + 1] == null ? ObjectId.zeroId().name() : expected[i + 1];
      assertThat(actual.oldRev).isEqualTo(oldRev);
      assertThat(actual.newRev).isEqualTo(newRev);
      i += 2;
    }
  }

  public void assertRefUpdatedEvents(String project, String branch, RevCommit... expected)
      throws Exception {
    ImmutableList<RefUpdatedEvent> events =
        getRefUpdatedEvents(project, branch, expected.length / 2);
    int i = 0;
    for (RefUpdatedEvent event : events) {
      RefUpdateAttribute actual = event.refUpdate.get();
      String oldRev = expected[i] == null ? ObjectId.zeroId().name() : expected[i].name();
      String newRev = expected[i + 1] == null ? ObjectId.zeroId().name() : expected[i + 1].name();
      assertThat(actual.oldRev).isEqualTo(oldRev);
      assertThat(actual.newRev).isEqualTo(newRev);
      i += 2;
    }
  }

  public void assertChangeMergedEvents(String project, String branch, String... expected)
      throws Exception {
    ImmutableList<ChangeMergedEvent> events =
        getChangeMergedEvents(project, branch, expected.length / 2);
    int i = 0;
    for (ChangeMergedEvent event : events) {
      String id = event.change.get().id;
      assertThat(id).isEqualTo(expected[i]);
      assertThat(event.newRev).isEqualTo(expected[i + 1]);
      i += 2;
    }
  }

  public void assertReviewerDeletedEvents(String... expected) {
    ImmutableList<ReviewerDeletedEvent> events = getReviewerDeletedEvents(expected.length / 2);
    int i = 0;
    for (ReviewerDeletedEvent event : events) {
      String id = event.change.get().id;
      assertThat(id).isEqualTo(expected[i]);
      String reviewer = event.reviewer.get().email;
      assertThat(reviewer).isEqualTo(expected[i + 1]);
      i += 2;
    }
  }

  public void assertChangeDeletedEvents(String... expected) {
    ImmutableList<ChangeDeletedEvent> events = getChangeDeletedEvents(expected.length / 2);
    int i = 0;
    for (ChangeDeletedEvent event : events) {
      String id = event.change.get().id;
      assertThat(id).isEqualTo(expected[i]);
      String reviewer = event.deleter.get().email;
      assertThat(reviewer).isEqualTo(expected[i + 1]);
      i += 2;
    }
  }

  public void close() {
    eventListenerRegistration.remove();
  }
}
