/*
 * 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.functions;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Path;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;

import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.Scope;
import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.InternalCacheForClientAccess;
import org.apache.geode.internal.cache.InternalRegionArguments;
import org.apache.geode.internal.cache.execute.InternalFunction;
import org.apache.geode.logging.internal.log4j.LogLevel;
import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.management.internal.cli.commands.ExportLogsCommand;
import org.apache.geode.management.internal.cli.util.ExportLogsCacheWriter;
import org.apache.geode.management.internal.cli.util.LogExporter;
import org.apache.geode.management.internal.cli.util.LogFilter;
import org.apache.geode.management.internal.configuration.domain.Configuration;

/**
 * this function extracts the logs using a LogExporter which creates a zip file, and then writes the
 * zip file bytes into a replicated region, this in effect, "stream" the zip file bytes to the
 * locator
 *
 * The function only extracts .log and .gfs files under server's working directory
 */
public class ExportLogsFunction implements InternalFunction {
  private static final Logger logger = LogService.getLogger();

  public static final String EXPORT_LOGS_REGION = "__exportLogsRegion";

  private static final long serialVersionUID = 1L;
  private static final int BUFFER_SIZE = 1024;

  @Override
  public void execute(final FunctionContext context) {
    try {
      InternalCache cache = (InternalCache) context.getCache();
      DistributionConfig config = cache.getInternalDistributedSystem().getConfig();

      String memberId = cache.getDistributedSystem().getMemberId();
      logger.info("ExportLogsFunction started for member {}", memberId);

      Region exportLogsRegion = createOrGetExistingExportLogsRegion(false, cache);

      Args args = (Args) context.getArguments();
      File baseLogFile = null;
      File baseStatsFile = null;

      if (args.isIncludeLogs() && !config.getLogFile().toString().isEmpty()) {
        baseLogFile = config.getLogFile().getAbsoluteFile();
      }
      if (args.isIncludeStats() && !config.getStatisticArchiveFile().toString().isEmpty()) {
        baseStatsFile = config.getStatisticArchiveFile().getAbsoluteFile();
      }

      LogFilter logFilter = new LogFilter(args.getLogLevel(), args.isThisLogLevelOnly(),
          args.getStartTime(), args.getEndTime());

      Path exportedZipFile = new LogExporter(logFilter, baseLogFile, baseStatsFile).export();

      // nothing to return back
      if (exportedZipFile == null) {
        context.getResultSender().lastResult(null);
        return;
      }

      logger.info("Streaming zipped file: " + exportedZipFile.toString());
      try (FileInputStream inputStream = new FileInputStream(exportedZipFile.toFile())) {
        byte[] buffer = new byte[BUFFER_SIZE];

        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) > 0) {
          if (bytesRead == BUFFER_SIZE) {
            exportLogsRegion.put(memberId, buffer);
          } else {
            exportLogsRegion.put(memberId, Arrays.copyOfRange(buffer, 0, bytesRead));
          }
        }
      }

      context.getResultSender().lastResult(null);

    } catch (Exception e) {
      e.printStackTrace();
      logger.error(e);
      context.getResultSender().sendException(e);
    }
  }

  public static Region createOrGetExistingExportLogsRegion(boolean isInitiatingMember,
      InternalCache cache) throws IOException, ClassNotFoundException {

    InternalCacheForClientAccess cacheForClientAccess = cache.getCacheForProcessingClientRequests();
    Region exportLogsRegion = cacheForClientAccess.getInternalRegion(EXPORT_LOGS_REGION);
    if (exportLogsRegion == null) {
      AttributesFactory<String, Configuration> regionAttrsFactory = new AttributesFactory<>();
      regionAttrsFactory.setDataPolicy(DataPolicy.EMPTY);
      regionAttrsFactory.setScope(Scope.DISTRIBUTED_ACK);

      if (isInitiatingMember) {
        regionAttrsFactory.setCacheWriter(new ExportLogsCacheWriter());
      }
      InternalRegionArguments internalArgs = new InternalRegionArguments();
      internalArgs.setIsUsedForMetaRegion(true);
      exportLogsRegion =
          cacheForClientAccess.createInternalRegion(EXPORT_LOGS_REGION, regionAttrsFactory.create(),
              internalArgs);
    }

    return exportLogsRegion;
  }

  public static void destroyExportLogsRegion(InternalCache cache) {
    Region exportLogsRegion =
        cache.getCacheForProcessingClientRequests().getInternalRegion(EXPORT_LOGS_REGION);
    if (exportLogsRegion == null) {
      return;
    }
    exportLogsRegion.destroyRegion();
  }

  @Override
  public boolean isHA() {
    return false;
  }

  public static class Args implements Serializable {
    private LocalDateTime startTime;
    private LocalDateTime endTime;
    private Level logLevel;
    private boolean thisLogLevelOnly;
    private boolean includeLogs;
    private boolean includeStats;

    public Args(String startTime, String endTime, String logLevel, boolean logLevelOnly,
        boolean logsOnly, boolean statsOnly) {
      this.startTime = parseTime(startTime);
      this.endTime = parseTime(endTime);

      if (StringUtils.isBlank(logLevel)) {
        this.logLevel = LogLevel.getLevel(ExportLogsCommand.DEFAULT_EXPORT_LOG_LEVEL);
      } else {
        this.logLevel = LogLevel.getLevel(logLevel);
      }
      this.thisLogLevelOnly = logLevelOnly;

      this.includeLogs = !statsOnly;
      this.includeStats = !logsOnly;
    }

    public LocalDateTime getStartTime() {
      return startTime;
    }

    public LocalDateTime getEndTime() {
      return endTime;
    }

    public Level getLogLevel() {
      return logLevel;
    }

    public boolean isThisLogLevelOnly() {
      return thisLogLevelOnly;
    }

    public boolean isIncludeLogs() {
      return includeLogs;
    }

    public boolean isIncludeStats() {
      return includeStats;
    }
  }

  public static LocalDateTime parseTime(String dateString) {
    if (dateString == null) {
      return null;
    }

    try {
      SimpleDateFormat df = new SimpleDateFormat(ExportLogsCommand.FORMAT);
      return df.parse(dateString).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    } catch (ParseException e) {
      try {
        SimpleDateFormat df = new SimpleDateFormat(ExportLogsCommand.ONLY_DATE_FORMAT);
        return df.parse(dateString).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
      } catch (ParseException e1) {
        return null;
      }
    }
  }
}
