// 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.server.events;

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

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
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.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
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.gson.Gson;
import org.junit.Test;

public class EventDeserializerTest {
  private final Gson gson = new EventGsonProvider().get();

  @Test
  public void refUpdatedEvent() {
    RefUpdatedEvent orig = new RefUpdatedEvent();
    RefUpdateAttribute refUpdatedAttribute = new RefUpdateAttribute();
    refUpdatedAttribute.refName = "refs/heads/master";
    orig.refUpdate = createSupplier(refUpdatedAttribute);

    AccountAttribute accountAttribute = new AccountAttribute();
    accountAttribute.email = "some.user@domain.com";
    orig.submitter = createSupplier(accountAttribute);

    RefUpdatedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertThat(e.refUpdate).isInstanceOf(Supplier.class);
    assertThat(e.refUpdate.get().refName).isEqualTo(refUpdatedAttribute.refName);
    assertThat(e.submitter).isInstanceOf(Supplier.class);
    assertThat(e.submitter.get().email).isEqualTo(accountAttribute.email);
  }

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

    PatchSetCreatedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
    assertSameAccount(e.uploader, orig.uploader);
  }

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

    ChangeDeletedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
    assertSameAccount(e.deleter, orig.deleter);
  }

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

    HashtagsChangedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
    assertSameAccount(e.editor, orig.editor);
    assertThat(e.added).isEqualTo(orig.added);
    assertThat(e.removed).isEqualTo(orig.removed);
    assertThat(e.hashtags).isEqualTo(orig.hashtags);
  }

  @Test
  public void customKeyedValuesChangedEvent() {
    Change change = newChange();
    CustomKeyedValuesChangedEvent orig = new CustomKeyedValuesChangedEvent(change);
    orig.change = asChangeAttribute(change);
    orig.editor = newAccount("editor");
    orig.added = ImmutableMap.of("key1", "value1");
    orig.removed = new String[] {"removed"};
    orig.customKeyedValues = ImmutableMap.of("key2", "value2");

    CustomKeyedValuesChangedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
    assertSameAccount(e.editor, orig.editor);
    assertThat(e.added).isEqualTo(orig.added);
    assertThat(e.removed).isEqualTo(orig.removed);
    assertThat(e.customKeyedValues).isEqualTo(orig.customKeyedValues);
  }

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

    ChangeAbandonedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
    assertSameAccount(e.abandoner, orig.abandoner);
    assertThat(e.reason).isEqualTo(orig.reason);
  }

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

    ChangeMergedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
  }

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

    ChangeRestoredEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
  }

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

    CommentAddedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
  }

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

    PrivateStateChangedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
  }

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

    ReviewerAddedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
  }

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

    ReviewerDeletedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
  }

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

    VoteDeletedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
  }

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

    WorkInProgressStateChangedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
  }

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

    TopicChangedEvent e = roundTrip(orig);

    assertThat(e).isNotNull();
    assertSameChangeEvent(e, orig);
  }

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

    ProjectHeadUpdatedEvent actual = roundTrip(event);

    assertThat(actual).isNotNull();
    assertThat(actual.projectName).isEqualTo(event.projectName);
    assertThat(actual.oldHead).isEqualTo(event.oldHead);
    assertThat(actual.newHead).isEqualTo(event.newHead);
  }

  @Test
  public void shouldSerializeAllProjectsToString() {
    String allProjectsString = "foobar";
    AllProjectsName allProjectsNameKey = new AllProjectsName(allProjectsString);

    assertThat(gson.toJson(allProjectsNameKey))
        .isEqualTo(String.format("\"%s\"", allProjectsString));
  }

  @Test
  public void shouldSerializeAllUsersToString() {
    String allUsersString = "foobar";
    AllUsersName allUsersNameKey = new AllUsersName(allUsersString);

    assertThat(gson.toJson(allUsersNameKey)).isEqualTo(String.format("\"%s\"", allUsersString));
  }

  @Test
  public void shouldSerializeProjectNameKeyToString() {
    String projectString = "foobar";
    Project.NameKey projectNameKey = Project.nameKey(projectString);

    assertThat(gson.toJson(projectNameKey)).isEqualTo(String.format("\"%s\"", projectString));
  }

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

  private Change newChange() {
    Change change =
        new Change(
            Change.key("Ideadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
            Change.id(1000),
            Account.id(1000),
            BranchNameKey.create(Project.nameKey("myproject"), "mybranch"),
            TimeUtil.now());
    return change;
  }

  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 void assertSameChangeEvent(ChangeEvent current, ChangeEvent expected) {
    assertThat(current.changeKey.get()).isEqualTo(expected.changeKey.get());
    assertThat(current.refName).isEqualTo(expected.refName);
    assertThat(current.project).isEqualTo(expected.project);
    assertSameChange(current.change, expected.change);
  }

  private void assertSameChange(
      Supplier<ChangeAttribute> currentSupplier, Supplier<ChangeAttribute> expectedSupplier) {
    ChangeAttribute current = currentSupplier.get();
    ChangeAttribute expected = expectedSupplier.get();
    assertThat(current.project).isEqualTo(expected.project);
    assertThat(current.branch).isEqualTo(expected.branch);
    assertThat(current.topic).isEqualTo(expected.topic);
    assertThat(current.id).isEqualTo(expected.id);
    assertThat(current.number).isEqualTo(expected.number);
    assertThat(current.subject).isEqualTo(expected.subject);
    assertThat(current.commitMessage).isEqualTo(expected.commitMessage);
    assertThat(current.url).isEqualTo(expected.url);
    assertThat(current.status).isEqualTo(expected.status);
    assertThat(current.createdOn).isEqualTo(expected.createdOn);
    assertThat(current.wip).isEqualTo(expected.wip);
    assertThat(current.isPrivate).isEqualTo(expected.isPrivate);
  }

  private void assertSameAccount(
      Supplier<AccountAttribute> currentSupplier, Supplier<AccountAttribute> expectedSupplier) {
    AccountAttribute current = currentSupplier.get();
    AccountAttribute expected = expectedSupplier.get();
    assertThat(current.name).isEqualTo(expected.name);
    assertThat(current.email).isEqualTo(expected.email);
    assertThat(current.username).isEqualTo(expected.username);
  }

  public 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 = "This is a test commit message";
    a.url = "http://somewhere.com";
    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);
  }

  @SuppressWarnings("unchecked")
  private <E extends Event> E roundTrip(E event) {
    String json = gson.toJson(event);
    return (E) gson.fromJson(json, event.getClass());
  }
}
