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

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

  @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 assigneeChangedEvent() {
    Change change = newChange();
    AssigneeChangedEvent event = new AssigneeChangedEvent(change);
    event.change = asChangeAttribute(change);
    event.changer = newAccount("changer");
    event.oldAssignee = newAccount("oldAssignee");

    assertThatJsonMap(event)
        .isEqualTo(
            ImmutableMap.builder()
                .put(
                    "changer",
                    ImmutableMap.builder()
                        .put("name", event.changer.get().name)
                        .put("email", event.changer.get().email)
                        .put("username", event.changer.get().username)
                        .build())
                .put(
                    "oldAssignee",
                    ImmutableMap.builder()
                        .put("name", event.oldAssignee.get().name)
                        .put("email", event.oldAssignee.get().email)
                        .put("username", event.oldAssignee.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", "assignee-changed")
                .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());
  }

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

  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().getTime() / 1000L;
    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);
  }
}
