// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.lib.util;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
import static org.mockito.Mockito.when;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
import java.util.logging.FileHandler;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;

/** Tests for the {@link FileHandlerQuerier} class. */
@RunWith(JUnit4.class)
public class FileHandlerQuerierTest {
  @Rule public TemporaryFolder tmp = new TemporaryFolder();

  private Logger getLoggerWithFileHandler(FileHandler handler) {
    Logger logger = Logger.getAnonymousLogger();
    logger.addHandler(handler);
    return logger;
  }

  private Logger getLoggerWithFileHandler(Path logPath) throws IOException {
    return getLoggerWithFileHandler(new FileHandler(logPath.toString()));
  }

  @Test
  public void getLoggerFilePath_onExpectedConfigurationOpenFile_returnsPath() throws Exception {
    Path configuredLogPath = Paths.get(tmp.getRoot().toString(), "hello.log");
    LogManager mockLogManager = Mockito.mock(LogManager.class);
    when(mockLogManager.getProperty("java.util.logging.FileHandler.pattern"))
        .thenReturn(configuredLogPath.toString());
    Logger logger = getLoggerWithFileHandler(configuredLogPath);
    FileHandlerQuerier handlerQuerier = new FileHandlerQuerier(() -> mockLogManager);

    Optional<Path> retrievedLogPath = handlerQuerier.getLoggerFilePath(logger);

    assertThat(retrievedLogPath).isPresent();
    assertThat(retrievedLogPath.get().toString()).isEqualTo(configuredLogPath.toString());
  }

  @Test
  public void getLoggerFilePath_onExpectedConfigurationClosedFile_returnsEmpty() throws Exception {
    Path configuredLogPath = Paths.get(tmp.getRoot().toString(), "hello.log");
    LogManager mockLogManager = Mockito.mock(LogManager.class);
    when(mockLogManager.getProperty("java.util.logging.FileHandler.pattern"))
        .thenReturn(configuredLogPath.toString());
    FileHandler handler = new FileHandler(configuredLogPath.toString());
    Logger logger = getLoggerWithFileHandler(handler);
    FileHandlerQuerier handlerQuerier = new FileHandlerQuerier(() -> mockLogManager);
    handler.close();

    assertThat(handlerQuerier.getLoggerFilePath(logger)).isEmpty();
  }

  @Test
  public void getLoggerFilePath_onMissingConfiguration_fails() throws Exception {
    Path configuredLogPath = Paths.get(tmp.getRoot().toString(), "hello.log");
    LogManager mockLogManager = Mockito.mock(LogManager.class);
    when(mockLogManager.getProperty("java.util.logging.FileHandler.pattern")).thenReturn(null);
    Logger logger = getLoggerWithFileHandler(configuredLogPath);
    FileHandlerQuerier handlerQuerier = new FileHandlerQuerier(() -> mockLogManager);

    assertThrows(IllegalStateException.class, () -> handlerQuerier.getLoggerFilePath(logger));
  }

  @Test
  public void getLoggerFilePath_onVariablesInPath_fails() throws Exception {
    LogManager mockLogManager = Mockito.mock(LogManager.class);
    when(mockLogManager.getProperty("java.util.logging.FileHandler.pattern"))
        .thenReturn(tmp.getRoot() + File.separator + "hello_%u.log");
    Logger logger =
        getLoggerWithFileHandler(Paths.get(tmp.getRoot().toString(), "hello_0.log"));
    FileHandlerQuerier handlerQuerier = new FileHandlerQuerier();

    assertThrows(IllegalStateException.class, () -> handlerQuerier.getLoggerFilePath(logger));
  }

  @Test
  public void getLoggerFilePath_onUnsupportedLogHandler_fails() throws Exception {
    FileHandlerQuerier handlerQuerier = new FileHandlerQuerier();
    Logger logger = Logger.getAnonymousLogger();
    logger.addHandler(
        SimpleLogHandler.builder().setPrefix(tmp.getRoot() + File.separator + "hello.log").build());

    assertThrows(IllegalArgumentException.class, () -> handlerQuerier.getLoggerFilePath(logger));
  }

  @Test
  public void getLoggerFilePath_onMissingLogHandler_fails() throws Exception {
    FileHandlerQuerier handlerQuerier = new FileHandlerQuerier();
    Logger logger = Logger.getAnonymousLogger();

    assertThrows(IllegalArgumentException.class, () -> handlerQuerier.getLoggerFilePath(logger));
  }
}
