// Copyright (C) 2015 Ericsson
//
// 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.ericsson.gerrit.plugins.highavailability.forwarder.rest;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.common.base.Joiner;
import com.google.gerrit.server.events.Event;
import com.google.gson.GsonBuilder;

import com.ericsson.gerrit.plugins.highavailability.forwarder.rest.HttpResponseHandler.HttpResult;

import org.junit.Test;

import java.io.IOException;

public class RestForwarderTest {
  private static final int CHANGE_NUMBER = 1;
  private static final String DELETE_OP = "delete";
  private static final String INDEX_OP = "index";
  private static final String PLUGIN_NAME = "high-availability";
  private static final String EMPTY_MSG = "";
  private static final String ERROR_MSG = "Error";
  private static final String EXCEPTION_MSG = "Exception";
  private static final boolean SUCCESSFUL = true;
  private static final boolean FAILED = false;
  private static final boolean DO_NOT_THROW_EXCEPTION = false;
  private static final boolean THROW_EXCEPTION = true;

  private RestForwarder restForwarder;

  @Test
  public void testIndexChangeOK() throws Exception {
    setUpMocksForIndex(INDEX_OP, SUCCESSFUL, EMPTY_MSG, DO_NOT_THROW_EXCEPTION);
    assertThat(restForwarder.indexChange(CHANGE_NUMBER)).isTrue();
  }

  @Test
  public void testIndexChangeFailed() throws Exception {
    setUpMocksForIndex(INDEX_OP, FAILED, ERROR_MSG, DO_NOT_THROW_EXCEPTION);
    assertThat(restForwarder.indexChange(CHANGE_NUMBER)).isFalse();
  }

  @Test
  public void testIndexChangeThrowsException() throws Exception {
    setUpMocksForIndex(INDEX_OP, FAILED, EXCEPTION_MSG, THROW_EXCEPTION);
    assertThat(restForwarder.indexChange(CHANGE_NUMBER)).isFalse();
  }

  @Test
  public void testChangeDeletedFromIndexOK() throws Exception {
    setUpMocksForIndex(DELETE_OP, SUCCESSFUL, EMPTY_MSG,
        DO_NOT_THROW_EXCEPTION);
    assertThat(restForwarder.deleteChangeFromIndex(CHANGE_NUMBER)).isTrue();
  }

  @Test
  public void testChangeDeletedFromIndexFailed() throws Exception {
    setUpMocksForIndex(DELETE_OP, FAILED, ERROR_MSG, DO_NOT_THROW_EXCEPTION);
    assertThat(restForwarder.deleteChangeFromIndex(CHANGE_NUMBER)).isFalse();
  }

  @Test
  public void testChangeDeletedFromThrowsException() throws Exception {
    setUpMocksForIndex(DELETE_OP, FAILED, EXCEPTION_MSG, THROW_EXCEPTION);
    assertThat(restForwarder.deleteChangeFromIndex(CHANGE_NUMBER)).isFalse();
  }

  private void setUpMocksForIndex(String operation,
      boolean isOperationSuccessful, String msg, boolean exception)
      throws Exception {
    String request =
        Joiner.on("/").join("/plugins", PLUGIN_NAME, INDEX_OP, CHANGE_NUMBER);
    HttpSession httpSession = mock(HttpSession.class);
    if (exception) {
      if (operation.equals(INDEX_OP)) {
        doThrow(new IOException()).when(httpSession).post(request);
      } else {
        doThrow(new IOException()).when(httpSession).delete(request);
      }
    } else {
      HttpResult result = new HttpResult(isOperationSuccessful, msg);
      if (operation.equals(INDEX_OP)) {
        when(httpSession.post(request)).thenReturn(result);
      } else {
        when(httpSession.delete(request)).thenReturn(result);
      }
    }
    restForwarder = new RestForwarder(httpSession, PLUGIN_NAME);
  }

  @Test
  public void testEventSentOK() throws Exception {
    Event event = setUpMocksForEvent(true, "", false);
    assertThat(restForwarder.send(event)).isTrue();
  }

  @Test
  public void testEventSentFailed() throws Exception {
    Event event = setUpMocksForEvent(false, "Error", false);
    assertThat(restForwarder.send(event)).isFalse();
  }

  @Test
  public void testEventSentThrowsException() throws Exception {
    Event event = setUpMocksForEvent(false, "Exception", true);
    assertThat(restForwarder.send(event)).isFalse();
  }

  private Event setUpMocksForEvent(boolean isOperationSuccessful, String msg,
      boolean exception) throws Exception {
    Event event = new EventTest();
    String content = new GsonBuilder().create().toJson(event);
    HttpSession httpSession = mock(HttpSession.class);
    String request = Joiner.on("/").join("/plugins", PLUGIN_NAME, "event");
    if (exception) {
      doThrow(new IOException()).when(httpSession).post(request, content);
    } else {
      HttpResult result = new HttpResult(isOperationSuccessful, msg);
      when(httpSession.post(request, content)).thenReturn(result);
    }
    restForwarder = new RestForwarder(httpSession, PLUGIN_NAME);
    return event;
  }

  private class EventTest extends Event {
    public EventTest() {
      super("test-event");
    }
  }
}
