// Copyright (C) 2020 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.metricsreportercloudwatch;

import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

import com.google.common.base.Splitter;
import com.google.common.base.Stopwatch;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.metrics.Counter0;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.MetricMaker;
import com.google.inject.Inject;
import java.time.Duration;
import java.util.Enumeration;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.junit.Test;

@UseLocalDisk
@TestPlugin(
    name = "metrics-reporter-cloudwatch",
    sysModule = "com.googlesource.gerrit.plugins.metricsreportercloudwatch.GerritCloudwatchModule")
public class MetricsReporterCloudwatchIT extends LightweightPluginDaemonTest {
  private static final String TEST_METRIC_NAME = "test/metric/name";
  private static final long TEST_METRIC_INCREMENT = 1234567L;
  private static final String TEST_TIMEOUT = "10";
  private static final Duration TEST_TIMEOUT_DURATION =
      Duration.ofSeconds(Integer.valueOf(TEST_TIMEOUT));

  @Inject private MetricMaker metricMaker;
  private Counter0 testCounterMetric;

  @Override
  public void setUpTestPlugin() throws Exception {
    System.setProperty("aws.region", "us-west-1");

    testCounterMetric = metricMaker.newCounter(TEST_METRIC_NAME, new Description("test metric"));

    super.setUpTestPlugin();
  }

  @Test
  @GerritConfig(name = "plugin.metrics-reporter-cloudwatch.dryrun", value = "true")
  public void shouldCloudwatchReporterBeStartedInDryRun() throws Exception {
    InMemoryLoggerAppender dryRunMetricsOutput = newInMemoryLogger();

    waitUntil(() -> dryRunMetricsOutput.metricsStream().anyMatch(l -> l.contains("DRY RUN")));
  }

  @Test
  @GerritConfig(name = "plugin.metrics-reporter-cloudwatch.dryrun", value = "true")
  @GerritConfig(name = "plugin.metrics-reporter-cloudwatch.rate", value = TEST_TIMEOUT)
  public void shouldReportMetricValueToCloudwatch() throws Exception {
    InMemoryLoggerAppender dryRunMetricsOutput = newInMemoryLogger();

    testCounterMetric.incrementBy(TEST_METRIC_INCREMENT);

    waitUntil(
        () ->
            dryRunMetricsOutput
                .metricsStream()
                .filter(l -> l.contains("MetricName=" + TEST_METRIC_NAME))
                .anyMatch(l -> l.contains("Value=" + TEST_METRIC_INCREMENT)));
  }

  @Test
  @GerritConfig(name = "plugin.metrics-reporter-cloudwatch.dryrun", value = "true")
  @GerritConfig(
      name = "plugin.metrics-reporter-cloudwatch.excludeMetrics",
      value = TEST_METRIC_NAME)
  @GerritConfig(name = "plugin.metrics-reporter-cloudwatch.rate", value = TEST_TIMEOUT)
  public void shouldExcludeMetrics() {
    InMemoryLoggerAppender dryRunMetricsOutput = newInMemoryLogger();

    assertThrows(
        InterruptedException.class,
        () -> {
          waitUntil(
              () ->
                  dryRunMetricsOutput
                      .metricsStream()
                      .anyMatch(l -> l.contains("MetricName=" + TEST_METRIC_NAME)));
        });
  }

  private static InMemoryLoggerAppender newInMemoryLogger() {
    InMemoryLoggerAppender dryRunMetricsOutput = new InMemoryLoggerAppender();
    for (Enumeration<?> logger = LogManager.getCurrentLoggers(); logger.hasMoreElements(); ) {
      Logger log = (Logger) logger.nextElement();
      if (log.getName().contains("CloudWatchReporter")) {
        log.addAppender(dryRunMetricsOutput);
        log.setLevel(Level.DEBUG);
      }
    }
    return dryRunMetricsOutput;
  }

  private static void waitUntil(Supplier<Boolean> waitCondition) throws InterruptedException {
    Stopwatch stopwatch = Stopwatch.createStarted();
    while (!waitCondition.get()) {
      if (stopwatch.elapsed().compareTo(TEST_TIMEOUT_DURATION) > 0) {
        throw new InterruptedException();
      }
      MILLISECONDS.sleep(50);
    }
  }

  static class InMemoryLoggerAppender extends AppenderSkeleton {
    private final Splitter metricsDatumSplitter = Splitter.on("MetricDatum");

    private CopyOnWriteArrayList<String> logLines = new CopyOnWriteArrayList<>();

    @Override
    public void close() {}

    @Override
    public boolean requiresLayout() {
      return false;
    }

    @Override
    protected void append(LoggingEvent event) {
      String logMessage = event.getMessage().toString();
      logLines.add(logMessage);
    }

    public Stream<String> metricsStream() {
      return logLines.stream().flatMap(metricsDatumSplitter::splitToStream);
    }
  }
}
