/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.samza.monitor;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import org.apache.samza.SamzaException;
import org.apache.samza.config.MapConfig;
import org.apache.samza.metrics.MetricsRegistry;
import org.apache.samza.monitor.mock.DummyMonitorFactory;
import org.apache.samza.monitor.mock.ExceptionThrowingMonitorFactory;
import org.apache.samza.monitor.mock.MockMonitorFactory;
import org.apache.samza.rest.SamzaRestConfig;
import org.apache.samza.util.NoOpMetricsRegistry;
import org.junit.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.mockito.Mockito;

import static junit.framework.TestCase.assertTrue;
import static org.apache.samza.monitor.MonitorConfig.CONFIG_MONITOR_FACTORY_CLASS;
import static org.apache.samza.monitor.MonitorLoader.instantiateMonitor;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class TestMonitorService {

  private static final MetricsRegistry METRICS_REGISTRY = new NoOpMetricsRegistry();

  @Test
  public void testMonitorsShouldBeInstantiatedProperly() {
    // Test that a monitor should be instantiated properly by invoking
    // the appropriate factory method.
    Map<String, String> configMap = ImmutableMap.of(CONFIG_MONITOR_FACTORY_CLASS,
                                                    DummyMonitorFactory.class.getCanonicalName());
    Monitor monitor = null;
    try {
      monitor = MonitorLoader.instantiateMonitor("testMonitor", new MonitorConfig(new MapConfig(configMap)),
          METRICS_REGISTRY);
    } catch (InstantiationException e) {
      fail();
    }
    assertNotNull(monitor);
    // Object should implement the monitor().
    try {
      monitor.monitor();
    } catch (Exception e) {
      fail();
    }
  }

  @Test
  public void testShouldGroupRelevantMonitorConfigTogether() {
    // Test that Monitor Loader groups relevant config together.
    Map<String, String> firstMonitorConfig = ImmutableMap.of("monitor.monitor1.factory.class",
                                                             "org.apache.samza.monitor.DummyMonitor",
                                                             "monitor.monitor1.scheduling.interval.ms",
                                                             "100");
    Map<String, String> secondMonitorConfig = ImmutableMap.of("monitor.monitor2.factory.class",
                                                              "org.apache.samza.monitor.DummyMonitor",
                                                              "monitor.monitor2.scheduling.interval.ms",
                                                              "200");
    MapConfig mapConfig = new MapConfig(ImmutableList.of(firstMonitorConfig, secondMonitorConfig));
    MonitorConfig expectedFirstConfig = new MonitorConfig(new MapConfig(firstMonitorConfig).subset("monitor.monitor1."));
    MonitorConfig expectedSecondConfig = new MonitorConfig(new MapConfig(secondMonitorConfig).subset("monitor.monitor2."));
    Map<String, MonitorConfig> expected = ImmutableMap.of("monitor1", expectedFirstConfig, "monitor2", expectedSecondConfig);
    assertEquals(expected, MonitorConfig.getMonitorConfigs(mapConfig));
  }

  @Test
  public void testMonitorExceptionIsolation() {
    // Test that an exception from a monitor doesn't bubble up out of the scheduler.
    Map<String, String> configMap =
        ImmutableMap.of(String.format("monitor.name.%s", CONFIG_MONITOR_FACTORY_CLASS),
                        ExceptionThrowingMonitorFactory.class.getCanonicalName());
    SamzaRestConfig config = new SamzaRestConfig(new MapConfig(configMap));
    SamzaMonitorService monitorService = new SamzaMonitorService(config,
                                                                 METRICS_REGISTRY);

    // This will throw if the exception isn't caught within the provider.
    monitorService.start();
    monitorService.stop();
  }

  @Test
  public void testShouldNotFailWhenTheMonitorFactoryClassIsNotDefined()
      throws Exception {
    // Test that when MonitorFactoryClass is not defined in the config, monitor service
    // should not fail.
    Map<String, String> configMap = ImmutableMap.of("monitor.monitor1.config.key1", "configValue1",
                                                    "monitor.monitor1.config.key2", "configValue2",
                                                    String.format("monitor.MOCK_MONITOR.%s", CONFIG_MONITOR_FACTORY_CLASS),
                                                    MockMonitorFactory.class.getCanonicalName());

    SamzaRestConfig config = new SamzaRestConfig(new MapConfig(configMap));

    class SamzaMonitorServiceTest extends SamzaMonitorService {
      MetricsRegistry metricsRegistry;
      public SamzaMonitorServiceTest(SamzaRestConfig config, MetricsRegistry metricsRegistry) {
        super(config, metricsRegistry);
        this.metricsRegistry = metricsRegistry;
      }

      @Override
      public void createSchedulerAndScheduleMonitor(String monitorName, MonitorConfig monitorConfig, long schedulingIntervalInMs) {
        try {
          // immediately run monitor, without scheduling
          instantiateMonitor(monitorName, monitorConfig, metricsRegistry).monitor();
        } catch (Exception e) {
          fail();
        }
      }
    }

    SamzaMonitorService monitorService = new SamzaMonitorServiceTest(config,
        METRICS_REGISTRY);

    try {
      monitorService.start();
    } catch (Exception e) {
      fail();
    }
    Mockito.verify(MockMonitorFactory.MOCK_MONITOR, Mockito.times(1)).monitor();
  }

  @Test(expected = SamzaException.class)
  public void testShouldFailWhenTheMonitorFactoryClassIsInvalid() {
    // Test that when MonitorFactoryClass is defined in the config and is invalid,
    // monitor service should fail. Should throw back SamzaException.
    Map<String, String> configMap = ImmutableMap.of(String.format("monitor.name.%s", CONFIG_MONITOR_FACTORY_CLASS),
                                                    "RandomClassName");
    SamzaRestConfig config = new SamzaRestConfig(new MapConfig(configMap));
    SamzaMonitorService monitorService = new SamzaMonitorService(config,
                                                                 METRICS_REGISTRY);
    monitorService.start();
  }

  @Test
  public void testScheduledExecutorSchedulingProvider() {
    // Test that the monitor is scheduled by the ScheduledExecutorSchedulingProvider
    ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);

    // notifyingMonitor.monitor() should be called repeatedly.
    final CountDownLatch wasCalledLatch = new CountDownLatch(3);

    final Monitor notifyingMonitor = new Monitor() {
      @Override
      public void monitor() {
        wasCalledLatch.countDown();
      }
    };

    Runnable runnableMonitor = new Runnable() {
      public void run() {
        try {
          notifyingMonitor.monitor();
        } catch (Exception e) {
          // Must be caught because they are checked in monitor()
          fail();
        }
      }
    };

    // monitor should get called every 1ms, so if await() misses the first call, there will be more.
    executorService.scheduleAtFixedRate(runnableMonitor, 0, 1, TimeUnit.MILLISECONDS);

    try {
      assertTrue(wasCalledLatch.await(5L, TimeUnit.SECONDS));
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } finally {
      executorService.shutdownNow();
    }

  }
}