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

import static org.apache.geode.internal.logging.Configuration.MAIN_LOGGER_NAME;
import static org.apache.geode.internal.logging.Configuration.SECURITY_LOGGER_NAME;
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.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.File;
import java.net.URL;

import org.apache.logging.log4j.Logger;
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.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;

import org.apache.geode.distributed.ConfigurationProperties;
import org.apache.geode.internal.logging.LogConfig;
import org.apache.geode.internal.logging.LogConfigSupplier;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.internal.logging.SessionContext;
import org.apache.geode.internal.statistics.StatisticsConfig;
import org.apache.geode.test.assertj.LogFileAssert;
import org.apache.geode.test.junit.categories.LoggingTest;
import org.apache.geode.test.junit.categories.SecurityTest;

/**
 * Integration tests for main and security {@link LogWriterAppender}s, loggers, and
 * {@link ConfigurationProperties#LOG_FILE} and {@link ConfigurationProperties#SECURITY_LOG_FILE}.
 */
@Category({LoggingTest.class, SecurityTest.class})
public class BothLogWriterAppendersIntegrationTest {

  private static final String CONFIG_FILE_NAME = "BothLogWriterAppendersIntegrationTest_log4j2.xml";
  private static final String MAIN_APPENDER_NAME = "LOGWRITER";
  private static final String SECURITY_APPENDER_NAME = "SECURITYLOGWRITER";

  private static String configFilePath;

  private File securityLogFile;
  private Logger mainGeodeLogger;
  private Logger securityGeodeLogger;
  private String logMessage;
  private LogWriterAppender mainLogWriterAppender;
  private LogWriterAppender securityLogWriterAppender;

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

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

  @Rule
  public TestName testName = new TestName();

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

  @Before
  public void setUp() throws Exception {
    String name = testName.getMethodName();
    File mainLogFile = new File(temporaryFolder.getRoot(), name + ".log");
    securityLogFile = new File(temporaryFolder.getRoot(), name + "-security.log");

    LogConfig logConfig = mock(LogConfig.class);
    when(logConfig.getName()).thenReturn(name);
    when(logConfig.getLogFile()).thenReturn(mainLogFile);
    when(logConfig.getSecurityLogFile()).thenReturn(securityLogFile);

    LogConfigSupplier logConfigSupplier = mock(LogConfigSupplier.class);
    when(logConfigSupplier.getLogConfig()).thenReturn(logConfig);
    when(logConfigSupplier.getStatisticsConfig()).thenReturn(mock(StatisticsConfig.class));

    SessionContext sessionContext = mock(SessionContext.class);
    when(sessionContext.getLogConfigSupplier()).thenReturn(logConfigSupplier);

    mainGeodeLogger = LogService.getLogger(MAIN_LOGGER_NAME);
    securityGeodeLogger = LogService.getLogger(SECURITY_LOGGER_NAME);

    logMessage = "Logging in " + testName.getMethodName();

    mainLogWriterAppender = loggerContextRule.getAppender(MAIN_APPENDER_NAME,
        LogWriterAppender.class);
    securityLogWriterAppender = loggerContextRule.getAppender(SECURITY_APPENDER_NAME,
        LogWriterAppender.class);

    mainLogWriterAppender.createSession(sessionContext);
    mainLogWriterAppender.startSession();
    mainLogWriterAppender.clearLogEvents();

    securityLogWriterAppender.createSession(sessionContext);
    securityLogWriterAppender.startSession();
    securityLogWriterAppender.clearLogEvents();
  }

  @After
  public void tearDown() throws Exception {
    mainLogWriterAppender.stopSession();
    securityLogWriterAppender.stopSession();
  }

  @Test
  public void mainLogWriterAppenderLogEventsIsEmptyByDefault() {
    assertThat(mainLogWriterAppender.getLogEvents()).isEmpty();
  }

  @Test
  public void securityLogWriterAppenderLogEventsIsEmptyByDefault() {
    assertThat(securityLogWriterAppender.getLogEvents()).isEmpty();
  }

  @Test
  public void geodeLoggerAppendsToLogWriterAppender() {
    mainGeodeLogger.info(logMessage);

    assertThat(mainLogWriterAppender.getLogEvents()).hasSize(1);
  }

  @Test
  public void geodeLoggerDoesNotAppendToSecurityLogWriterAppender() {
    mainGeodeLogger.info(logMessage);

    assertThat(securityLogWriterAppender.getLogEvents()).isEmpty();
  }

  @Test
  public void geodeSecurityLoggerAppendsToSecurityLogWriterAppender() {
    securityGeodeLogger.info(logMessage);

    assertThat(securityLogWriterAppender.getLogEvents()).hasSize(1);
  }

  @Test
  public void geodeSecurityLoggerDoesNotAppendToLogWriterAppender() {
    securityGeodeLogger.info(logMessage);

    assertThat(mainLogWriterAppender.getLogEvents()).isEmpty();
  }

  @Test
  public void securityGeodeLoggerLogsToSecurityLogFile() {
    securityGeodeLogger.info(logMessage);

    LogFileAssert.assertThat(securityLogFile).exists().contains(logMessage);
  }

  @Test
  public void securityGeodeLoggerDoesNotLogToMainLogFile() {
    securityGeodeLogger.info(logMessage);

    assertThat(mainLogWriterAppender.getLogEvents()).isEmpty();
  }
}
