/*
 * 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.geode.logging.log4j.internal.impl;

import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
import static org.apache.geode.logging.internal.Configuration.LOG_LEVEL_UPDATE_OCCURS_PROPERTY;
import static org.apache.geode.logging.internal.spi.LogWriterLevel.CONFIG;
import static org.apache.geode.logging.internal.spi.LogWriterLevel.FINE;
import static org.apache.geode.logging.internal.spi.LogWriterLevel.WARNING;
import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
import static org.apache.geode.test.util.ResourceUtils.getResource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;

import java.net.URL;
import java.util.List;
import java.util.Properties;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.junit.LoggerContextRule;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.RestoreSystemProperties;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;

import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.logging.internal.spi.LogLevelUpdateOccurs;
import org.apache.geode.test.junit.categories.LoggingTest;

/**
 * Integration tests for {@link DistributedSystem} and log level changes with
 * {@link GeodeConsoleAppender}.
 */
@Category(LoggingTest.class)
public class DistributedSystemWithLogLevelChangesIntegrationTest {

  private static final String CONFIG_FILE_NAME =
      "DistributedSystemWithLogLevelChangesIntegrationTest_log4j2.xml";
  private static final String APPENDER_NAME = "STDOUT";
  private static final String APPLICATION_LOGGER_NAME = "com.company.application";

  private static String configFilePath;

  private InternalDistributedSystem system;
  private DistributionConfig distributionConfig;
  private Logger geodeLogger;
  private Logger applicationLogger;
  private String logMessage;
  private GeodeConsoleAppender geodeConsoleAppender;

  @ClassRule
  public static TemporaryFolder temporaryFolder = new TemporaryFolder();

  @Rule
  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);

  @Rule
  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();

  @Rule
  public TestName testName = new TestName();

  @BeforeClass
  public static void setUpLogConfigFile() {
    URL resource = getResource(CONFIG_FILE_NAME);
    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
        .getAbsolutePath();
  }

  @Before
  public void setUp() {
    System.setProperty(LOG_LEVEL_UPDATE_OCCURS_PROPERTY, LogLevelUpdateOccurs.ALWAYS.name());

    Properties config = new Properties();
    config.setProperty(LOCATORS, "");

    system = (InternalDistributedSystem) DistributedSystem.connect(config);

    distributionConfig = system.getConfig();
    geodeLogger = LogService.getLogger();
    applicationLogger = LogService.getLogger(APPLICATION_LOGGER_NAME);
    logMessage = "Logging in " + testName.getMethodName();
    geodeConsoleAppender =
        loggerContextRule.getAppender(APPENDER_NAME, GeodeConsoleAppender.class);
  }

  @After
  public void tearDown() {
    system.disconnect();
    geodeConsoleAppender.clearLogEvents();
  }

  @Test
  public void debugNotLoggedByDefault() {
    geodeLogger.debug(logMessage);

    assertThatLogEventsDoesNotContain(logMessage, getClass().getName(), Level.DEBUG);
  }

  @Test
  public void debugLoggedAfterLoweringLogLevelToFine() {
    distributionConfig.setLogLevel(FINE.intLevel());

    geodeLogger.debug(logMessage);

    assertThatLogEventsContains(logMessage, geodeLogger.getName(), Level.DEBUG);
  }

  @Test
  public void debugNotLoggedAfterRestoringLogLevelToDefault() {
    distributionConfig.setLogLevel(FINE.intLevel());

    system.getConfig().setLogLevel(CONFIG.intLevel());
    geodeLogger.debug(logMessage);

    assertThatLogEventsDoesNotContain(logMessage, geodeLogger.getName(), Level.DEBUG);
  }

  @Test
  public void applicationLoggerInfoLoggedByDefault() {
    applicationLogger.info(logMessage);

    assertThatLogEventsContains(logMessage, applicationLogger.getName(), Level.INFO);
  }

  @Test
  public void applicationLoggerBelowLevelUnaffectedByLoweringLogLevelChanges() {
    distributionConfig.setLogLevel(FINE.intLevel());

    applicationLogger.debug(logMessage);

    assertThatLogEventsDoesNotContain(logMessage, applicationLogger.getName(), Level.DEBUG);
  }

  @Test
  public void applicationLoggerAboveLevelUnaffectedByLoweringLogLevelChanges() {
    distributionConfig.setLogLevel(FINE.intLevel());

    applicationLogger.info(logMessage);

    assertThatLogEventsContains(logMessage, applicationLogger.getName(), Level.INFO);
  }

  @Test
  public void applicationLoggerAboveLevelUnaffectedByRaisingLogLevelChanges() {
    distributionConfig.setLogLevel(WARNING.intLevel());

    applicationLogger.info(logMessage);

    assertThatLogEventsContains(logMessage, applicationLogger.getName(), Level.INFO);
  }

  @Test
  public void infoStatementNotLoggedAfterRaisingLogLevelToWarning() {
    distributionConfig.setLogLevel(WARNING.intLevel());

    geodeLogger.info(logMessage);

    assertThatLogEventsDoesNotContain(logMessage, geodeLogger.getName(), Level.INFO);
  }

  private void assertThatLogEventsContains(String message, String loggerName, Level level) {
    List<LogEvent> logEvents = geodeConsoleAppender.getLogEvents();
    for (LogEvent logEvent : logEvents) {
      if (logEvent.getMessage().getFormattedMessage().contains(message)) {
        assertThat(logEvent.getMessage().getFormattedMessage()).isEqualTo(message);
        assertThat(logEvent.getLoggerName()).isEqualTo(loggerName);
        assertThat(logEvent.getLevel()).isEqualTo(level);
        return;
      }
    }
    fail("Expected message " + message + " not found in " + logEvents);
  }

  private void assertThatLogEventsDoesNotContain(String message, String loggerName, Level level) {
    List<LogEvent> logEvents = geodeConsoleAppender.getLogEvents();
    for (LogEvent logEvent : logEvents) {
      if (logEvent.getMessage().getFormattedMessage().contains(message) &&
          logEvent.getLoggerName().equals(loggerName) && logEvent.getLevel().equals(level)) {
        fail("Expected message " + message + " should not be contained in " + logEvents);
      }
    }
  }
}
