// Copyright (C) 2019 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.events;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.entities.Change.Status.NEW;

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.truth.MapSubject;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.data.AccountAttribute;
import com.google.gerrit.server.data.ChangeAttribute;
import com.google.gerrit.server.data.RefUpdateAttribute;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.testing.TestTimeUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;

public class EventJsonTest {
  private static final String BRANCH = "mybranch";
  private static final String CHANGE_ID = "Ideadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
  private static final int CHANGE_NUM = 1000;
  private static final double CHANGE_NUM_DOUBLE = CHANGE_NUM;
  private static final String COMMIT_MESSAGE = "This is a test commit message";
  private static final String PROJECT = "myproject";
  private static final String REF = "refs/heads/" + BRANCH;
  private static final double TS1 = 1.2543444E9;
  private static final double TS2 = 1.254344401E9;
  private static final String URL = "http://somewhere.com";

  private final Gson gson = new EventGsonProvider().get();

  static class CustomEvent extends Event {
    static String TYPE = "custom-type";

    public String customField;

    protected CustomEvent() {
      super(TYPE);
    }
  }

  @Before
  public void setTimeForTesting() {
    TestTimeUtil.resetWithClockStep(1, TimeUnit.SECONDS);
  }

  @Test
  public void customEvent() {
    CustomEvent event = new CustomEvent();
    event.customField = "customValue";
    String json = gson.toJson(event);
    CustomEvent resullt = gson.fromJson(json, CustomEvent.class);
    assertThat(resullt.type).isEqualTo(CustomEvent.TYPE);
    assertThat(resullt.customField).isEqualTo(event.customField);
  }

  @Test
  public void customEventSimulateClassloaderIssue() {
    EventTypes.register(CustomEvent.TYPE, CustomEvent.class);
    CustomEvent event = new CustomEvent();
    event.customField = "customValue";
    // Need to serialise using the Event interface instead of json.getClass()
    // for simulating the serialisation of an object owned by another class loader
    String json = gson.toJson(event, Event.class);
    CustomEvent resullt = gson.fromJson(json, CustomEvent.class);
    assertThat(resullt.type).isEqualTo(CustomEvent.TYPE);
    assertThat(resullt.customField).isEqualTo(event.customField);
  }

  @Test
  public void refUpdatedEvent() {
    RefUpdatedEvent event = new RefUpdatedEvent();

    RefUpdateAttribute refUpdatedAttribute = new RefUpdateAttribute();
    refUpdatedAttribute.refName = REF;
    event.refUpdate = createSupplier(refUpdatedAttribute);
    event.submitter = newAccount("submitter");

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "submitter",
                    ImmutableMap.builder()
                        .put("name", event.submitter.get().name)
                        .put("email", event.submitter.get().email)
                        .put("username", event.submitter.get().username)
                        .build())
                .put("refUpdate", ImmutableMap.of("refName", REF))
                .put("type", "ref-updated")
                .put("eventCreatedOn", TS1)
                .build());
  }

  @Test
  public void patchSetCreatedEvent() {
    Change change = newChange();
    PatchSetCreatedEvent event = new PatchSetCreatedEvent(change);
    event.change = asChangeAttribute(change);
    event.uploader = newAccount("uploader");

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "uploader",
                    ImmutableMap.builder()
                        .put("name", event.uploader.get().name)
                        .put("email", event.uploader.get().email)
                        .put("username", event.uploader.get().username)
                        .build())
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "patchset-created")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void changeDeletedEvent() {
    Change change = newChange();
    ChangeDeletedEvent event = new ChangeDeletedEvent(change);
    event.change = asChangeAttribute(change);
    event.deleter = newAccount("deleter");

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "deleter",
                    ImmutableMap.builder()
                        .put("name", event.deleter.get().name)
                        .put("email", event.deleter.get().email)
                        .put("username", event.deleter.get().username)
                        .build())
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "change-deleted")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void hashtagsChangedEvent() {
    Change change = newChange();
    HashtagsChangedEvent event = new HashtagsChangedEvent(change);
    event.change = asChangeAttribute(change);
    event.editor = newAccount("editor");
    event.added = new String[] {"added"};
    event.removed = new String[] {"removed"};
    event.hashtags = new String[] {"hashtags"};

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "editor",
                    ImmutableMap.builder()
                        .put("name", event.editor.get().name)
                        .put("email", event.editor.get().email)
                        .put("username", event.editor.get().username)
                        .build())
                .put("added", list("added"))
                .put("removed", list("removed"))
                .put("hashtags", list("hashtags"))
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "hashtags-changed")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void changeAbandonedEvent() {
    Change change = newChange();
    ChangeAbandonedEvent event = new ChangeAbandonedEvent(change);
    event.change = asChangeAttribute(change);
    event.abandoner = newAccount("abandoner");
    event.reason = "some reason";

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "abandoner",
                    ImmutableMap.builder()
                        .put("name", event.abandoner.get().name)
                        .put("email", event.abandoner.get().email)
                        .put("username", event.abandoner.get().username)
                        .build())
                .put("reason", "some reason")
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "change-abandoned")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void changeMergedEvent() {
    Change change = newChange();
    ChangeMergedEvent event = new ChangeMergedEvent(change);
    event.change = asChangeAttribute(change);

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "change-merged")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void changeRestoredEvent() {
    Change change = newChange();
    ChangeRestoredEvent event = new ChangeRestoredEvent(change);
    event.change = asChangeAttribute(change);

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "change-restored")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void commentAddedEvent() {
    Change change = newChange();
    CommentAddedEvent event = new CommentAddedEvent(change);
    event.change = asChangeAttribute(change);

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "comment-added")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void privateStateChangedEvent() {
    Change change = newChange();
    PrivateStateChangedEvent event = new PrivateStateChangedEvent(change);
    event.change = asChangeAttribute(change);

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "private-state-changed")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void reviewerAddedEvent() {
    Change change = newChange();
    ReviewerAddedEvent event = new ReviewerAddedEvent(change);
    event.change = asChangeAttribute(change);

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "reviewer-added")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void reviewerDeletedEvent() {
    Change change = newChange();
    ReviewerDeletedEvent event = new ReviewerDeletedEvent(change);
    event.change = asChangeAttribute(change);

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "reviewer-deleted")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void voteDeletedEvent() {
    Change change = newChange();
    VoteDeletedEvent event = new VoteDeletedEvent(change);
    event.change = asChangeAttribute(change);

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "vote-deleted")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void workInProgressStateChangedEvent() {
    Change change = newChange();
    WorkInProgressStateChangedEvent event = new WorkInProgressStateChangedEvent(change);
    event.change = asChangeAttribute(change);

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "wip-state-changed")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void topicChangedEvent() {
    Change change = newChange();
    TopicChangedEvent event = new TopicChangedEvent(change);
    event.change = asChangeAttribute(change);

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "change",
                    ImmutableMap.builder()
                        .put("project", PROJECT)
                        .put("branch", BRANCH)
                        .put("id", CHANGE_ID)
                        .put("number", CHANGE_NUM_DOUBLE)
                        .put("url", URL)
                        .put("commitMessage", COMMIT_MESSAGE)
                        .put("createdOn", TS1)
                        .put("status", NEW.name())
                        .build())
                .put("project", PROJECT)
                .put("refName", REF)
                .put("changeKey", map("id", CHANGE_ID))
                .put("type", "topic-changed")
                .put("eventCreatedOn", TS2)
                .build());
  }

  @Test
  public void projectCreatedEvent() {
    ProjectCreatedEvent event = new ProjectCreatedEvent();
    event.projectName = PROJECT;
    event.headName = REF;

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put("projectName", PROJECT)
                .put("headName", REF)
                .put("type", "project-created")
                .put("eventCreatedOn", TS1)
                .build());
  }

  @Test
  public void projectHeadUpdatedEvent() {
    ProjectHeadUpdatedEvent event = new ProjectHeadUpdatedEvent();
    event.projectName = PROJECT;
    event.oldHead = "refs/heads/master";
    event.newHead = REF;

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put("projectName", PROJECT)
                .put("oldHead", "refs/heads/master")
                .put("newHead", REF)
                .put("type", "project-head-updated")
                .put("eventCreatedOn", TS1)
                .build());
  }

  private Supplier<AccountAttribute> newAccount(String name) {
    AccountAttribute account = new AccountAttribute();
    account.name = name;
    account.email = name + "@somewhere.com";
    account.username = name;
    return Suppliers.ofInstance(account);
  }

  private Change newChange() {
    return new Change(
        Change.key(CHANGE_ID),
        Change.id(CHANGE_NUM),
        Account.id(9999),
        BranchNameKey.create(Project.nameKey(PROJECT), BRANCH),
        TimeUtil.now());
  }

  private <T> Supplier<T> createSupplier(T value) {
    return Suppliers.memoize(() -> value);
  }

  private Supplier<ChangeAttribute> asChangeAttribute(Change change) {
    ChangeAttribute a = new ChangeAttribute();
    a.project = change.getProject().get();
    a.branch = change.getDest().shortName();
    a.topic = change.getTopic();
    a.id = change.getKey().get();
    a.number = change.getId().get();
    a.subject = change.getSubject();
    a.commitMessage = COMMIT_MESSAGE;
    a.url = URL;
    a.status = change.getStatus();
    a.createdOn = change.getCreatedOn().getEpochSecond();
    a.wip = change.isWorkInProgress() ? true : null;
    a.isPrivate = change.isPrivate() ? true : null;
    return Suppliers.ofInstance(a);
  }

  private MapSubject assertThatJsonMap(Object src) {
    // Parse JSON into a raw Java map:
    //  * Doesn't depend on field iteration order.
    //  * Avoids excessively long string literals in asserts.
    String json = gson.toJson(src);
    Map<Object, Object> map =
        gson.fromJson(json, new TypeToken<Map<Object, Object>>() {}.getType());
    return assertThat(map);
  }

  private static ImmutableMap<Object, Object> map(Object k, Object v) {
    return ImmutableMap.of(k, v);
  }

  private static ImmutableList<Object> list(Object... es) {
    return ImmutableList.copyOf(es);
  }
}
