// Copyright (C) 2014 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.ericsson.gerrit.plugins.eventslog.sql;

import static com.ericsson.gerrit.plugins.eventslog.sql.SQLTable.TABLE_NAME;
import static com.google.common.truth.Truth.assertThat;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;

import com.google.gerrit.reviewdb.client.Change.Key;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.events.ChangeEvent;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gson.Gson;
import com.google.inject.Provider;

import com.ericsson.gerrit.plugins.eventslog.EventsLogConfig;
import com.ericsson.gerrit.plugins.eventslog.MalformedQueryException;
import com.ericsson.gerrit.plugins.eventslog.ServiceUnavailableException;
import com.ericsson.gerrit.plugins.eventslog.sql.SQLClient;
import com.ericsson.gerrit.plugins.eventslog.sql.SQLEntry;
import com.ericsson.gerrit.plugins.eventslog.sql.SQLStore;

import org.easymock.EasyMock;
import org.easymock.EasyMockSupport;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.ConnectException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class SQLStoreTest {
  private static final Logger log = LoggerFactory.getLogger(SQLStoreTest.class);
  private static final String TEST_URL = "jdbc:h2:mem:";
  private static final String TEST_LOCAL_URL = "jdbc:h2:mem:test:";
  private static final String TEST_DRIVER = "org.h2.Driver";
  private static final String TEST_OPTIONS = "DB_CLOSE_DELAY=-1";
  private static final String TERM_CONN_MSG = "terminating connection";
  private static final String MSG = "message";
  private static final String GENERIC_QUERY = "SELECT * FROM " + TABLE_NAME;

  private EasyMockSupport easyMock;
  private ProjectControl.GenericFactory pcFactoryMock;
  private Provider<CurrentUser> userProviderMock;
  private EventsLogConfig cfgMock;
  private SQLClient eventsDb;
  private SQLClient localEventsDb;
  private SQLStore store;
  private ScheduledThreadPoolExecutor poolMock;

  private String path = TEST_URL + TABLE_NAME + ";" + TEST_OPTIONS;
  private Connection conn;
  private Statement stat;
  private List<SQLEntry> results;

  @Rule
  public TemporaryFolder testFolder = new TemporaryFolder();

  @SuppressWarnings("unchecked")
  @Before
  public void setUp() throws SQLException {
    conn = DriverManager.getConnection(path);
    stat = conn.createStatement();
    results = new ArrayList<>();
    poolMock = new PoolMock(1);
    easyMock = new EasyMockSupport();
    pcFactoryMock = easyMock.createNiceMock(ProjectControl.GenericFactory.class);
    userProviderMock = easyMock.createNiceMock(Provider.class);
    cfgMock = easyMock.createNiceMock(EventsLogConfig.class);
    expect(cfgMock.getMaxAge()).andReturn(5);
    expect(cfgMock.getLocalStorePath()).andReturn(testFolder.getRoot().toPath()).atLeastOnce();
  }

  public void tearDown() throws Exception {
    stat.execute("DROP TABLE " + TABLE_NAME);
    store.stop();
  }

  private void setUpClient() {
    eventsDb = new SQLClient(TEST_DRIVER, TEST_URL, TEST_OPTIONS);
    localEventsDb = new SQLClient(TEST_DRIVER, TEST_LOCAL_URL, TEST_OPTIONS);
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    store.start();
  }

  private void setUpClientMock(boolean reset) throws SQLException {
    eventsDb = easyMock.createNiceMock(SQLClient.class);
    localEventsDb = easyMock.createNiceMock(SQLClient.class);
    expect(localEventsDb.dbExists()).andReturn(true).anyTimes();
    if (reset) {
      easyMock.resetAll();
    }
  }

  @Test
  public void storeThenQueryVisible() throws Exception {
    MockEvent mockEvent = new MockEvent();
    ProjectControl pcMock = easyMock.createNiceMock(ProjectControl.class);
    CurrentUser userMock = easyMock.createNiceMock(CurrentUser.class);
    expect(userProviderMock.get()).andStubReturn(userMock);
    expect(pcFactoryMock.controlFor(mockEvent.getProjectNameKey(), userMock))
        .andStubReturn(pcMock);
    expect(pcMock.isVisible()).andStubReturn(true);
    easyMock.replayAll();
    setUpClient();
    store.storeEvent(mockEvent);
    List<String> events = store.queryChangeEvents(GENERIC_QUERY);
    Gson gson = new Gson();
    String json = gson.toJson(mockEvent);
    assertThat(events).containsExactly(json);
    tearDown();
  }

  @Test
  public void storeThenQueryNotVisible() throws Exception {
    MockEvent mockEvent = new MockEvent();
    ProjectControl pcMock = easyMock.createNiceMock(ProjectControl.class);
    CurrentUser userMock = easyMock.createNiceMock(CurrentUser.class);
    expect(userProviderMock.get()).andStubReturn(userMock);
    expect(pcFactoryMock.controlFor(mockEvent.getProjectNameKey(), userMock))
        .andStubReturn(pcMock);
    expect(pcMock.isVisible()).andStubReturn(false);
    easyMock.replayAll();
    setUpClient();
    store.storeEvent(mockEvent);
    List<String> events = store.queryChangeEvents(GENERIC_QUERY);
    assertThat(events).isEmpty();
    tearDown();
  }

  @Test(expected = MalformedQueryException.class)
  public void throwBadRequestTriggerOnBadQuery() throws Exception {
    easyMock.replayAll();
    setUpClient();
    String badQuery = "bad query";
    store.queryChangeEvents(badQuery);
    easyMock.verifyAll();
  }

  @Test
  public void notReturnEventOfNonExistingProject() throws Exception {
    MockEvent mockEvent = new MockEvent();
    Project.NameKey projectMock = easyMock.createMock(Project.NameKey.class);
    expect(projectMock.get()).andStubReturn(" ");
    expect(
        pcFactoryMock.controlFor(EasyMock.anyObject(Project.NameKey.class),
            EasyMock.anyObject(CurrentUser.class)))
              .andThrow(new NoSuchProjectException(projectMock));
    easyMock.replayAll();
    setUpClient();
    store.storeEvent(mockEvent);
    List<String> events = store.queryChangeEvents(GENERIC_QUERY);
    assertThat(events).isEmpty();
    tearDown();
  }

  @Test
  public void notReturnEventWithNoVisibilityInfo() throws Exception {
    MockEvent mockEvent = new MockEvent();
    Project.NameKey projectMock = easyMock.createMock(Project.NameKey.class);
    expect(projectMock.get()).andStubReturn(" ");
    expect(
        pcFactoryMock.controlFor(EasyMock.anyObject(Project.NameKey.class),
            EasyMock.anyObject(CurrentUser.class))).andThrow(new IOException());
    easyMock.replayAll();
    setUpClient();
    store.storeEvent(mockEvent);
    List<String> events = store.queryChangeEvents(GENERIC_QUERY);
    assertThat(events).isEmpty();
    tearDown();
  }

  @Test
  public void retryOnConnectException() throws Exception {
    MockEvent mockEvent = new MockEvent();
    setUpClientMock(false);
    EasyMock.reset(eventsDb, localEventsDb);
    expect(cfgMock.getMaxTries()).andReturn(3).once();
    eventsDb.storeEvent(mockEvent);
    expectLastCall().andThrow(new SQLException(new ConnectException()))
        .times(3);
    expect(localEventsDb.getAll()).andStubReturn(results);
    easyMock.replayAll();
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    store.start();

    store.storeEvent(mockEvent);
    easyMock.verifyAll();
  }

  @Test
  public void retryOnMessage() throws Exception {
    MockEvent mockEvent = new MockEvent();
    setUpClientMock(false);
    expect(cfgMock.getMaxTries()).andReturn(3).once();
    eventsDb.storeEvent(mockEvent);
    expectLastCall().andThrow(new SQLException(TERM_CONN_MSG)).times(3);
    expect(localEventsDb.getAll()).andStubReturn(results);
    easyMock.replayAll();
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    store.start();

    store.storeEvent(mockEvent);
    easyMock.verifyAll();
  }

  @Test
  public void noRetryOnMessage() throws Exception {
    MockEvent mockEvent = new MockEvent();
    setUpClientMock(false);
    expect(cfgMock.getMaxTries()).andReturn(3).once();
    eventsDb.storeEvent(mockEvent);
    expectLastCall().andThrow(new SQLException(MSG)).once();
    expect(localEventsDb.getAll()).andReturn(results);
    easyMock.replayAll();
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    store.start();

    store.storeEvent(mockEvent);
    easyMock.verifyAll();
  }

  @Test
  public void noRetryOnZeroMaxTries() throws Exception {
    MockEvent mockEvent = new MockEvent();
    setUpClientMock(false);
    expect(cfgMock.getMaxTries()).andReturn(0).once();
    eventsDb.storeEvent(mockEvent);
    expectLastCall().andThrow(new SQLException(new ConnectException())).once();
    expect(localEventsDb.getAll()).andStubReturn(results);
    easyMock.replayAll();
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    store.start();

    store.storeEvent(mockEvent);
    easyMock.verifyAll();
  }

  @Test (expected = ServiceUnavailableException.class)
  public void throwSQLExceptionIfNotOnline() throws Exception {
    MockEvent mockEvent = new MockEvent();
    setUpClientMock(true);
    eventsDb.createDBIfNotCreated();
    expectLastCall().andThrow(new SQLException(new ConnectException())).once();
    eventsDb.queryOne();
    expectLastCall().andThrow(new SQLException());
    easyMock.replayAll();
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    store.start();
    store.storeEvent(mockEvent);
    store.queryChangeEvents(GENERIC_QUERY);
    easyMock.verifyAll();
  }

  @Test
  public void restoreFromLocalAndRemoveUnfoundProjectEvents() throws Exception {
    MockEvent mockEvent = new MockEvent();
    MockEvent mockEvent2 = new MockEvent("proj");
    MockEvent mockEvent3 = new MockEvent("unfound");

    ProjectControl pc = easyMock.createNiceMock(ProjectControl.class);
    NoSuchProjectException e =
        easyMock.createNiceMock(NoSuchProjectException.class);
    expect(
        pcFactoryMock.controlFor(EasyMock.anyObject(Project.NameKey.class),
            EasyMock.anyObject(CurrentUser.class))).andReturn(pc).times(2);
    expect(pc.isVisible()).andReturn(true).times(2);
    expect(
        pcFactoryMock.controlFor(EasyMock.anyObject(Project.NameKey.class),
            EasyMock.anyObject(CurrentUser.class))).andThrow(e);
    easyMock.replayAll();

    eventsDb = new SQLClient(TEST_DRIVER, TEST_URL, TEST_OPTIONS);
    localEventsDb = new SQLClient(TEST_DRIVER, TEST_LOCAL_URL, TEST_OPTIONS);
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);

    localEventsDb.createDBIfNotCreated();
    localEventsDb.storeEvent(mockEvent);
    localEventsDb.storeEvent(mockEvent2);
    localEventsDb.storeEvent(mockEvent3);
    store.start();
    List<String> events = store.queryChangeEvents(GENERIC_QUERY);
    Gson gson = new Gson();
    String json = gson.toJson(mockEvent);
    String json2 = gson.toJson(mockEvent2);
    assertThat(events).containsExactly(json, json2);
    easyMock.verifyAll();
    tearDown();
  }

  @Test
  public void offlineUponStart() throws Exception {
    setUpClientMock(true);
    eventsDb.createDBIfNotCreated();
    expectLastCall().andThrow(new SQLException(new ConnectException())).once();
    eventsDb.queryOne();
    expectLastCall().andThrow(new SQLException());
    easyMock.replayAll();
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    store.start();
    easyMock.verifyAll();
  }

  @Test
  public void storeLocalOffline() throws Exception {
    MockEvent mockEvent = new MockEvent();
    setUpClientMock(true);
    eventsDb.createDBIfNotCreated();
    expectLastCall().andThrow(new SQLException(new ConnectException())).once();
    localEventsDb.storeEvent(mockEvent);
    expectLastCall().once();
    eventsDb.queryOne();
    expectLastCall().andThrow(new SQLException());
    easyMock.replayAll();
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    store.start();

    store.storeEvent(mockEvent);
    easyMock.verifyAll();
  }

  @Test
  public void storeLocalOfflineAfterNoRetry() throws Exception {
    MockEvent mockEvent = new MockEvent();
    setUpClientMock(false);
    expect(cfgMock.getMaxTries()).andReturn(0).once();
    eventsDb.storeEvent(mockEvent);
    expectLastCall().andThrow(new SQLException(new ConnectException())).once();
    expect(localEventsDb.getAll()).andStubReturn(results);
    easyMock.replayAll();
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    store.start();

    store.storeEvent(mockEvent);
    easyMock.verifyAll();
  }

  /**
   * For this test we expect that if we can connect to main database, then we
   * should come back online and try setting up again. We just want to make sure
   * that restoreEventsFromLocal gets called, so verifying that getLocalDBFile
   * is called is sufficient.
   */
  @Test
  public void testConnectionTask() throws Exception {
    eventsDb = new SQLClient(TEST_DRIVER, TEST_URL, TEST_OPTIONS);
    localEventsDb = easyMock.createMock(SQLClient.class);
    expect(localEventsDb.dbExists()).andReturn(true).once();
    expect(localEventsDb.getAll()).andReturn(new ArrayList<SQLEntry>());
    easyMock.replayAll();
    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    eventsDb.createDBIfNotCreated();
    poolMock.scheduleWithFixedDelay(store.new CheckConnectionTask(), 0, 0,
        TimeUnit.MILLISECONDS);
    easyMock.verifyAll();
  }

  @Test
  public void checkConnectionAndRestoreCopyLocal() throws Exception {
    checkConnectionAndRestore(true);
  }

  @Test
  public void checkConnectionAndRestoreNoCopyLocal() throws Exception {
    checkConnectionAndRestore(false);
  }

  private void checkConnectionAndRestore(boolean copy) throws Exception {
    MockEvent mockEvent = new MockEvent();
    eventsDb = easyMock.createNiceMock(SQLClient.class);
    localEventsDb = new SQLClient(TEST_DRIVER, TEST_LOCAL_URL, TEST_OPTIONS);
    localEventsDb.createDBIfNotCreated();
    localEventsDb.storeEvent(mockEvent);
    eventsDb.createDBIfNotCreated();
    expectLastCall().andThrow(new SQLException(new ConnectException())).once();
    eventsDb.queryOne();
    expectLastCall().once();
    eventsDb.storeEvent(EasyMock.anyString(),
        EasyMock.anyObject(Timestamp.class), EasyMock.anyString());
    expectLastCall().once();

    if (copy) {
      testCopyLocal();
    }
    easyMock.replayAll();

    store =
        new SQLStore(pcFactoryMock, userProviderMock, cfgMock, eventsDb,
            localEventsDb, poolMock);
    store.start();
    List<SQLEntry> entries = localEventsDb.getAll();
    assertThat(entries).isEmpty();
    easyMock.verifyAll();
  }

  private void testCopyLocal() {
    expect(cfgMock.getCopyLocal()).andReturn(true).once();
  }

  public class MockEvent extends ChangeEvent {
    public String project = "mock project";

    MockEvent() {
      super("mock event");
    }

    MockEvent(String project) {
      this();
      this.project = project;
    }

    @Override
    public Project.NameKey getProjectNameKey() {
      return new Project.NameKey(project);
    }

    @Override
    public Key getChangeKey() {
      return null;
    }

    @Override
    public String getRefName() {
      return null;
    }
  }

  class PoolMock extends ScheduledThreadPoolExecutor {
    PoolMock(int corePoolSize) {
      super(corePoolSize);
    }

    @Override
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
        long initialDelay, long delay, TimeUnit unit) {
      log.info(command.toString());
      command.run();
      return null;
    }
  }
}
