/*
 * 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.LogWriterLevel.CONFIG;
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.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.SessionContext;
import org.apache.geode.internal.statistics.StatisticsConfig;
import org.apache.geode.test.junit.categories.LoggingTest;

/**
 * Integration tests for {@link LogWriterAppender} with
 * {@link ConfigurationProperties#LOG_FILE_SIZE_LIMIT} and
 * {@link ConfigurationProperties#LOG_DISK_SPACE_LIMIT}.
 */
@Category(LoggingTest.class)
public class LogWriterAppenderWithLimitsIntegrationTest {

  private static final String CONFIG_FILE_NAME =
      "LogWriterAppenderWithLimitsIntegrationTest_log4j2.xml";
  private static final String APPENDER_NAME = "LOGWRITER";
  private static final int MAX_LOG_DISK_SPACE_LIMIT = 1_000_000;
  private static final int MAX_LOG_FILE_SIZE_LIMIT = 1_000_000;

  private static String configFilePath;

  private LogWriterAppender logWriterAppender;
  private LogConfig config;

  @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 {
    logWriterAppender = loggerContextRule.getAppender(APPENDER_NAME,
        LogWriterAppender.class);

    String name = testName.getMethodName();
    File logFile = temporaryFolder.newFile(name + ".log");

    config = mock(LogConfig.class);
    when(config.getName()).thenReturn(name);
    when(config.getLogFile()).thenReturn(logFile);
    when(config.getLogLevel()).thenReturn(CONFIG.intLevel());
    when(config.getLogDiskSpaceLimit()).thenReturn(MAX_LOG_DISK_SPACE_LIMIT);
    when(config.getLogFileSizeLimit()).thenReturn(MAX_LOG_FILE_SIZE_LIMIT);

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

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

    logWriterAppender.createSession(sessionContext);
  }

  @After
  public void tearDown() throws Exception {
    logWriterAppender.clearLogEvents();
  }

  @Test
  public void logDiskSpaceLimit() {
    // log-disk-space-limit starts out as MAX_LOG_DISK_SPACE_LIMIT
    LogConfig logConfig = logWriterAppender.getLogWriter().getConfig();
    assertThat(logConfig.getLogDiskSpaceLimit()).isEqualTo(MAX_LOG_DISK_SPACE_LIMIT);

    // log-disk-space-limit changes to 1_000
    when(config.getLogDiskSpaceLimit()).thenReturn(1_000);
    logWriterAppender.configChanged();

    assertThat(logConfig.getLogDiskSpaceLimit()).isEqualTo(1_000);

    // log-disk-space-limit changes back to MAX_LOG_DISK_SPACE_LIMIT
    when(config.getLogDiskSpaceLimit()).thenReturn(MAX_LOG_DISK_SPACE_LIMIT);
    logWriterAppender.configChanged();

    assertThat(logConfig.getLogDiskSpaceLimit()).isEqualTo(MAX_LOG_DISK_SPACE_LIMIT);
  }

  @Test
  public void logFileSizeLimit() {
    // log-file-size-limit starts out as MAX_LOG_FILE_SIZE_LIMIT
    LogConfig logConfig = logWriterAppender.getLogWriter().getConfig();
    assertThat(logConfig.getLogFileSizeLimit()).isEqualTo(MAX_LOG_FILE_SIZE_LIMIT);

    // log-file-size-limit changes to 1_000
    when(config.getLogFileSizeLimit()).thenReturn(1_000);
    logWriterAppender.configChanged();

    assertThat(logConfig.getLogFileSizeLimit()).isEqualTo(1_000);

    // log-disk-space-limit changes back to MAX_LOG_FILE_SIZE_LIMIT
    when(config.getLogFileSizeLimit()).thenReturn(MAX_LOG_FILE_SIZE_LIMIT);
    logWriterAppender.configChanged();

    assertThat(logConfig.getLogFileSizeLimit()).isEqualTo(MAX_LOG_FILE_SIZE_LIMIT);
  }
}
