// 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.googlesource.gerrit.plugins.multisite.broker.kafka;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.only;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.google.gerrit.extensions.client.ChangeKind;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.BranchNameKey;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.data.AccountAttribute;
import com.google.gerrit.server.data.ApprovalAttribute;
import com.google.gerrit.server.events.CommentAddedEvent;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.EventGsonProvider;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.googlesource.gerrit.plugins.multisite.DisabledMessageLogger;
import com.googlesource.gerrit.plugins.multisite.MessageLogger;
import com.googlesource.gerrit.plugins.multisite.broker.BrokerMetrics;
import com.googlesource.gerrit.plugins.multisite.broker.BrokerPublisher;
import com.googlesource.gerrit.plugins.multisite.broker.BrokerSession;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventFamily;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class BrokerPublisherTest {

  @Mock private BrokerMetrics brokerMetrics;
  @Mock private BrokerSession session;
  private BrokerPublisher publisher;

  private MessageLogger NO_MSG_LOG = new DisabledMessageLogger();
  private Gson gson = new EventGsonProvider().get();

  private String accountName = "Foo Bar";
  private String accountEmail = "foo@bar.com";
  private String accountUsername = "foobar";
  private String approvalType = ChangeKind.REWORK.toString();

  private String approvalDescription = "ApprovalDescription";
  private String approvalValue = "+2";
  private String oldApprovalValue = "+1";
  private Long approvalGrantedOn = 123L;
  private String commentDescription = "Patch Set 1: Code-Review+2";
  private String projectName = "project";
  private String refName = "refs/heads/master";
  private String changeId = "Iabcd1234abcd1234abcd1234abcd1234abcd1234";
  private Long eventCreatedOn = 123L;

  @Before
  public void setUp() {
    publisher = new BrokerPublisher(session, gson, UUID.randomUUID(), NO_MSG_LOG, brokerMetrics);
  }

  @Test
  public void shouldSerializeCommentAddedEvent() {

    Event event = createSampleEvent();

    String expectedSerializedCommentEvent =
        "{\"author\": {\"name\": \""
            + accountName
            + "\",\"email\": \""
            + accountEmail
            + "\",\"username\": \""
            + accountUsername
            + "\"},\"approvals\": [{\"type\": \""
            + approvalType
            + "\",\"description\": \""
            + approvalDescription
            + "\",\"value\": \""
            + approvalValue
            + "\",\"oldValue\": \""
            + oldApprovalValue
            + "\",\"grantedOn\": "
            + approvalGrantedOn
            + ",\"by\": {\"name\": \""
            + accountName
            + "\",\"email\": \""
            + accountEmail
            + "\",\"username\": \""
            + accountUsername
            + "\"}}],\"comment\": \""
            + commentDescription
            + "\",\"project\": \""
            + projectName
            + "\",\"refName\": \""
            + refName
            + "\",\"changeKey\": {\"id\": \""
            + changeId
            + "\""
            + "  },\"type\": \"comment-added\",\"eventCreatedOn\": "
            + eventCreatedOn
            + "}";

    JsonObject expectedCommentEventJsonObject =
        gson.fromJson(expectedSerializedCommentEvent, JsonElement.class).getAsJsonObject();

    assertThat(publisher.eventToJson(event)).isEqualTo(expectedCommentEventJsonObject);
  }

  @Test
  public void shouldIncrementBrokerMetricCounterWhenMessagePublished() {
    Event event = createSampleEvent();
    when(session.publishEvent(any(), any())).thenReturn(true);
    publisher.publishEvent(EventFamily.INDEX_EVENT, event);
    verify(brokerMetrics, only()).incrementBrokerPublishedMessage();
  }

  @Test
  public void shouldIncrementBrokerFailedMetricCounterWhenMessagePublished() {
    Event event = createSampleEvent();
    when(session.publishEvent(any(), any())).thenReturn(false);

    publisher.publishEvent(EventFamily.INDEX_EVENT, event);
    verify(brokerMetrics, only()).incrementBrokerFailedToPublishMessage();
  }

  private Event createSampleEvent() {
    final Change change =
        new Change(
            Change.key(changeId),
            Change.id(1),
            Account.id(1),
            BranchNameKey.create(projectName, refName),
            TimeUtil.nowTs());

    CommentAddedEvent event = new CommentAddedEvent(change);
    AccountAttribute accountAttribute = new AccountAttribute();
    accountAttribute.email = accountEmail;
    accountAttribute.name = accountName;
    accountAttribute.username = accountUsername;

    event.eventCreatedOn = eventCreatedOn;
    event.approvals =
        () -> {
          ApprovalAttribute approvalAttribute = new ApprovalAttribute();
          approvalAttribute.value = approvalValue;
          approvalAttribute.oldValue = oldApprovalValue;
          approvalAttribute.description = approvalDescription;
          approvalAttribute.by = accountAttribute;
          approvalAttribute.type = ChangeKind.REWORK.toString();
          approvalAttribute.grantedOn = approvalGrantedOn;

          return new ApprovalAttribute[] {approvalAttribute};
        };

    event.author = () -> accountAttribute;
    event.comment = commentDescription;

    return event;
  }
}
