// 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();
  }
}
