// 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.websession.broker;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import com.gerritforge.gerrit.eventbroker.BrokerApi;
import com.gerritforge.gerrit.eventbroker.EventMessage;
import com.gerritforge.gerrit.eventbroker.EventMessage.Header;
import com.google.common.cache.Cache;
import com.google.common.collect.Maps;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.httpd.WebSessionManager.Val;
import com.google.gerrit.server.config.PluginConfig;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.events.Event;
import com.googlesource.gerrit.plugins.websession.broker.BrokerBasedWebSessionCache.WebSessionEvent;
import com.googlesource.gerrit.plugins.websession.broker.BrokerBasedWebSessionCache.WebSessionEvent.Operation;
import com.googlesource.gerrit.plugins.websession.broker.log.WebSessionLogger;
import com.googlesource.gerrit.plugins.websession.broker.util.TimeMachine;
import java.time.Instant;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class BrokerBasedWebSessionCacheTest {

  private static final int DEFAULT_ACCOUNT_ID = 1000000;
  private static final String KEY = "aSceprtma6B0qZ0hKxXHvQ5iyfUhCcFXxG";
  private static final String PLUGIN_NAME = "websession-broker";

  private byte[] emptyPayload = new byte[] {-84, -19, 0, 5, 112};
  byte[] defaultPayload =
      new byte[] {
        -84, -19, 0, 5, 115, 114, 0, 45, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46, 103,
        101, 114, 114, 105, 116, 46, 104, 116, 116, 112, 100, 46, 87, 101, 98, 83, 101, 115, 115,
        105, 111, 110, 77, 97, 110, 97, 103, 101, 114, 36, 86, 97, 108, 0, 0, 0, 0, 0, 0, 0, 2, 3,
        0, 0, 120, 112, 119, 97, 1, -64, -124, 61, 2, 0, 0, 1, 111, 13, -8, 90, 7, 3, 0, 5, 34, 97,
        83, 99, 101, 112, 114, 113, 86, 87, 54, 85, 79, 45, 88, 51, 107, 51, 116, 102, 85, 109, 86,
        103, 82, 73, 90, 56, 53, 99, 99, 52, 71, 114, 87, 6, 0, 0, 1, 111, 16, 84, -103, -121, 7,
        34, 97, 83, 99, 101, 112, 114, 114, 82, 103, 119, 49, 71, 110, 90, 56, 122, 54, 49, 49, 86,
        52, 121, 110, 65, 100, 110, 113, 99, 68, 45, 105, 99, 75, 97, 0, 120
      };

  @Mock BrokerApi brokerApi;
  @Mock Cache<String, Val> cache;
  @Mock TimeMachine timeMachine;
  @Mock PluginConfigFactory cfg;
  @Mock PluginConfig pluginConfig;
  @Mock WebSessionLogger webSessionLogger;
  @Captor ArgumentCaptor<EventMessage> eventCaptor;
  @Captor ArgumentCaptor<Val> valCaptor;

  BrokerBasedWebSessionCache objectUnderTest;

  @Before
  public void setup() {
    when(pluginConfig.getString("webSessionTopic", "gerrit_web_session"))
        .thenReturn("gerrit_web_session");
    when(cfg.getFromGerritConfig(PLUGIN_NAME)).thenReturn(pluginConfig);
    when(timeMachine.now()).thenReturn(Instant.EPOCH);
    DynamicItem<BrokerApi> item = DynamicItem.itemOf(BrokerApi.class, brokerApi);
    objectUnderTest =
        new BrokerBasedWebSessionCache(
            cache, item, timeMachine, cfg, PLUGIN_NAME, webSessionLogger);
  }

  @Test
  public void shouldPublishMessageWhenLoginEvent() {
    EventMessage eventMessage = createEventMessage();
    Val value = createVal(eventMessage);
    when(brokerApi.newMessage(any(UUID.class), any(Event.class))).thenReturn(eventMessage);

    objectUnderTest.put(KEY, value);

    verify(brokerApi, times(1)).send(anyString(), eventCaptor.capture());

    assertThat(eventCaptor.getValue().getEvent()).isNotNull();
    WebSessionEvent event = (WebSessionEvent) eventCaptor.getValue().getEvent();
    assertThat(event.operation).isEqualTo(WebSessionEvent.Operation.ADD);
    assertThat(event.key).isEqualTo(KEY);
    assertThat(event.payload).isEqualTo(defaultPayload);
  }

  @Test
  public void shouldPublishMessageWhenLogoutEvent() {
    EventMessage eventMessage = createEventMessage(emptyPayload, Operation.REMOVE);
    when(brokerApi.newMessage(any(UUID.class), any(Event.class))).thenReturn(eventMessage);

    objectUnderTest.invalidate(KEY);

    verify(brokerApi, times(1)).send(anyString(), eventCaptor.capture());

    assertThat(eventCaptor.getValue().getEvent()).isNotNull();
    WebSessionEvent event = (WebSessionEvent) eventCaptor.getValue().getEvent();
    assertThat(event.operation).isEqualTo(WebSessionEvent.Operation.REMOVE);
    assertThat(event.key).isEqualTo(KEY);
    assertThat(event.payload).isEqualTo(emptyPayload);
  }

  @Test
  public void shouldUpdateCacheWhenLoginMessageReceived() {
    EventMessage eventMessage = createEventMessage();

    objectUnderTest.processMessage(eventMessage);

    verify(cache, times(1)).put(anyString(), valCaptor.capture());

    assertThat(valCaptor.getValue()).isNotNull();
    Val val = valCaptor.getValue();
    assertThat(val.getAccountId().get()).isEqualTo(DEFAULT_ACCOUNT_ID);
  }

  @Test
  public void shouldUpdateCacheWhenLogoutMessageReceived() {
    EventMessage eventMessage = createEventMessage(emptyPayload, Operation.REMOVE);

    objectUnderTest.processMessage(eventMessage);

    verify(cache, times(1)).invalidate(KEY);
  }

  @Test
  public void shouldSkipCacheUpdateWhenUnknownEventType() {
    Header header =
        new Header(
            UUID.fromString("7cb80dbe-65c4-4f2c-84de-580d98199d4a"),
            UUID.fromString("97711495-1013-414e-bfd2-44776787520d"));
    Event event = new Event("sample-event") {};
    EventMessage eventMessage = new EventMessage(header, event);
    objectUnderTest.processMessage(eventMessage);

    verifyZeroInteractions(cache);
  }

  @Test
  public void shouldSkipCacheUpdateWhenInvalidPayload() {
    EventMessage eventMessage = createEventMessage(new byte[] {1, 2, 3, 4}, Operation.ADD);
    objectUnderTest.processMessage(eventMessage);

    verifyZeroInteractions(cache);
  }

  @Test
  public void shouldSkipCacheUpdateWhenSessionExpired() {
    when(timeMachine.now()).thenReturn(Instant.MAX);
    EventMessage eventMessage = createEventMessage();
    objectUnderTest.processMessage(eventMessage);

    verifyZeroInteractions(cache);
  }

  @Test
  public void shouldCleanupExpiredSessions() {
    when(timeMachine.now()).thenReturn(Instant.MIN, Instant.MAX);

    EventMessage eventMessage = createEventMessage();

    objectUnderTest.processMessage(eventMessage);
    verify(cache, times(1)).put(anyString(), valCaptor.capture());
    assertThat(valCaptor.getValue()).isNotNull();

    ConcurrentMap<String, Val> cacheMap = Maps.newConcurrentMap();
    cacheMap.put(KEY, valCaptor.getValue());
    when(cache.asMap()).thenReturn(cacheMap);

    objectUnderTest.cleanUp();

    verify(cache, times(1)).invalidate(KEY);
  }

  @SuppressWarnings("unchecked")
  private Val createVal(EventMessage message) {
    ArgumentCaptor<Val> valArgumentCaptor = ArgumentCaptor.forClass(Val.class);

    objectUnderTest.processMessage(message);
    verify(cache).put(anyString(), valArgumentCaptor.capture());
    reset(cache);
    return valArgumentCaptor.getValue();
  }

  private EventMessage createEventMessage() {

    return createEventMessage(defaultPayload, Operation.ADD);
  }

  private EventMessage createEventMessage(byte[] payload, Operation operation) {

    Header header =
        new Header(
            UUID.fromString("7cb80dbe-65c4-4f2c-84de-580d98199d4a"),
            UUID.fromString("97711495-1013-414e-bfd2-44776787520d"));
    WebSessionEvent event = new WebSessionEvent(KEY, payload, operation);
    return new EventMessage(header, event);
  }
}
