/*
 * 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.management.internal.cli.util;

import static java.util.stream.Collectors.toList;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.Logger;

import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.management.internal.configuration.utils.ZipUtils;

/**
 * this LogExporter only finds the .log and .gfs files under in the same directory of the base files
 * it doesn't use the base file's filename patterns to find the related logs/stats yet.
 */
public class LogExporter {
  private static final Logger LOGGER = LogService.getLogger();

  private final LogFilter logFilter;
  private final File baseLogFile;
  private final File baseStatsFile;

  /**
   * @param logFilter the filter that's used to check if we need to accept the file or the logLine
   * @param baseLogFile if not null, we will export the logs in that directory
   * @param baseStatsFile if not null, we will export stats in that directory
   */
  public LogExporter(LogFilter logFilter, File baseLogFile, File baseStatsFile) {
    assert logFilter != null;
    this.logFilter = logFilter;
    this.baseLogFile = baseLogFile;
    this.baseStatsFile = baseStatsFile;
  }

  /**
   *
   * @return Path to the zip file that has all the filtered files, null if no files are selected to
   *         export.
   */
  public Path export() throws IOException {
    Path tempDirectory = Files.createTempDirectory("exportLogs");

    if (baseLogFile != null) {
      for (Path logFile : findLogFiles(baseLogFile.toPath().getParent())) {
        Path filteredLogFile = tempDirectory.resolve(logFile.getFileName());
        writeFilteredLogFile(logFile, filteredLogFile);
      }
    }

    if (baseStatsFile != null) {
      for (Path statFile : findStatFiles(baseStatsFile.toPath().getParent())) {
        Files.copy(statFile, tempDirectory.resolve(statFile.getFileName()));
      }
    }

    Path zipFile = null;
    if (tempDirectory.toFile().listFiles().length > 0) {
      zipFile = Files.createTempFile("logExport", ".zip");
      ZipUtils.zipDirectory(tempDirectory, zipFile);
      LOGGER.info("Zipped files to: " + zipFile);
    }

    FileUtils.deleteDirectory(tempDirectory.toFile());

    return zipFile;
  }

  protected void writeFilteredLogFile(Path originalLogFile, Path filteredLogFile)
      throws IOException {
    this.logFilter.startNewFile();

    try (BufferedReader reader = new BufferedReader(new FileReader(originalLogFile.toFile()))) {
      try (BufferedWriter writer = new BufferedWriter(new FileWriter(filteredLogFile.toFile()))) {

        String line;
        while ((line = reader.readLine()) != null) {
          LogFilter.LineFilterResult result = this.logFilter.acceptsLine(line);

          if (result == LogFilter.LineFilterResult.REMAINDER_OF_FILE_REJECTED) {
            break;
          }

          if (result == LogFilter.LineFilterResult.LINE_ACCEPTED) {
            writeLine(line, writer);
          }
        }
      }
    }
  }

  private void writeLine(String line, BufferedWriter writer) {
    try {
      writer.write(line);
      writer.newLine();
    } catch (IOException e) {
      throw new RuntimeException("Unable to write to log file", e);
    }
  }

  /**
   * @return combined size of stat archives and filtered log files in bytes
   */
  public long estimateFilteredSize() throws IOException {
    long filteredSize = 0;
    if (baseLogFile != null) {
      for (Path logFile : findLogFiles(baseLogFile.toPath().getParent())) {
        filteredSize += filterAndSize(logFile);
      }
    }

    if (baseStatsFile != null) {
      for (Path statFile : findStatFiles(baseStatsFile.toPath().getParent())) {
        filteredSize += statFile.toFile().length();
      }
    }

    return filteredSize;
  }

  /**
   * @return size of file in bytes
   */
  private long filterAndSize(Path originalLogFile) throws IOException {
    long size = 0;
    this.logFilter.startNewFile();

    try (BufferedReader reader = new BufferedReader(new FileReader(originalLogFile.toFile()))) {
      String line;
      while ((line = reader.readLine()) != null) {
        LogFilter.LineFilterResult result = this.logFilter.acceptsLine(line);

        if (result == LogFilter.LineFilterResult.REMAINDER_OF_FILE_REJECTED) {
          break;
        }
        if (result == LogFilter.LineFilterResult.LINE_ACCEPTED) {
          size += line.length() + System.lineSeparator().length();
        }
      }
    }
    return size;
  }

  List<Path> findLogFiles(Path workingDir) throws IOException {
    Predicate<Path> logFileSelector = (Path file) -> file.toString().toLowerCase().contains(".log");
    return findFiles(workingDir, logFileSelector);
  }


  List<Path> findStatFiles(Path workingDir) throws IOException {
    Predicate<Path> statFileSelector =
        (Path file) -> file.toString().toLowerCase().endsWith(".gfs");
    return findFiles(workingDir, statFileSelector);
  }

  private List<Path> findFiles(Path workingDir, Predicate<Path> fileSelector) throws IOException {
    Stream<Path> selectedFiles/* = null */;
    if (!workingDir.toFile().isDirectory()) {
      return Collections.emptyList();
    }
    selectedFiles = Files.list(workingDir).filter(fileSelector).filter(this.logFilter::acceptsFile);

    return selectedFiles.collect(toList());
  }
}
