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

import org.apache.logging.log4j.Logger;

import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.execute.InternalFunction;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.management.ManagementException;
import org.apache.geode.management.internal.cli.util.BytesToString;
import org.apache.geode.management.internal.cli.util.LogExporter;
import org.apache.geode.management.internal.cli.util.LogFilter;

public class SizeExportLogsFunction extends ExportLogsFunction implements InternalFunction {
  private static final Logger LOGGER = LogService.getLogger();
  private static final long serialVersionUID = 1L;

  @Override
  public void execute(final FunctionContext context) {
    try {
      InternalCache cache = (InternalCache) context.getCache();
      DistributionConfig config = cache.getInternalDistributedSystem().getConfig();
      Args args = (Args) context.getArguments();
      long diskAvailable = getDiskAvailable(config);
      long estimatedSize = estimateLogFileSize(cache.getMyId(), config.getLogFile(),
          config.getStatisticArchiveFile(), args);

      BytesToString bytesToString = new BytesToString();
      if (estimatedSize == 0 || estimatedSize < diskAvailable) {
        context.getResultSender().lastResult(estimatedSize);
      } else {
        StringBuilder sb = new StringBuilder().append("Estimated disk space required (")
            .append(bytesToString.of(estimatedSize)).append(") to consolidate logs on member ")
            .append(cache.getName()).append(" will exceed available disk space (")
            .append(bytesToString.of(diskAvailable)).append(")");
        context.getResultSender().sendException(new ManagementException(sb.toString())); // FileTooBigException
      }

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

  long getDiskAvailable(DistributionConfig config) {
    return config.getLogFile().getUsableSpace();
  }

  long estimateLogFileSize(final DistributedMember member, final File logFile,
      final File statArchive, final Args args) throws IOException {
    if (LOGGER.isDebugEnabled()) {
      LOGGER.debug("SizeExportLogsFunction started for member {}", member);
    }

    File baseLogFile = null;
    File baseStatsFile = null;

    if (args.isIncludeLogs() && !logFile.toString().isEmpty()) {
      baseLogFile = logFile.getAbsoluteFile();
    }
    if (args.isIncludeStats() && !statArchive.toString().isEmpty()) {
      baseStatsFile = statArchive.getAbsoluteFile();
    }

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

    long estimatedSize =
        new LogExporter(logFilter, baseLogFile, baseStatsFile).estimateFilteredSize();

    LOGGER.info("Estimated log file size: " + estimatedSize);

    return estimatedSize;
  }
}
