/**
* 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.hadoop.yarn.server.nodemanager.containermanager.logaggregation;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileContext;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.factories.RecordFactory;
import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider;
import org.apache.hadoop.yarn.server.nodemanager.NMConfig;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.logaggregation.AggregatedLogFormat.LogKey;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.logaggregation.AggregatedLogFormat.LogReader;
import org.apache.hadoop.yarn.util.ConverterUtils;

public class LogDumper extends Configured implements Tool {

  private static final String CONTAINER_ID_OPTION = "containerId";
  private static final String APPLICATION_ID_OPTION = "applicationId";
  private static final String NODE_ADDRESS_OPTION = "nodeAddress";

  @Override
  public int run(String[] args) throws Exception {

    Options opts = new Options();
    opts.addOption(APPLICATION_ID_OPTION, true, "ApplicationId");
    opts.addOption(CONTAINER_ID_OPTION, true, "ContainerId");
    opts.addOption(NODE_ADDRESS_OPTION, true, "NodeAddress");

    if (args.length < 1) {
      HelpFormatter formatter = new HelpFormatter();
      formatter.printHelp("general options are: ", opts);
      return -1;
    }

    CommandLineParser parser = new GnuParser();
    String appIdStr = null;
    String containerIdStr = null;
    String nodeAddress = null;
    try {
      CommandLine commandLine = parser.parse(opts, args, true);
      appIdStr = commandLine.getOptionValue(APPLICATION_ID_OPTION);
      containerIdStr = commandLine.getOptionValue(CONTAINER_ID_OPTION);
      nodeAddress = commandLine.getOptionValue(NODE_ADDRESS_OPTION);
    } catch (ParseException e) {
      System.out.println("options parsing failed: " + e.getMessage());

      HelpFormatter formatter = new HelpFormatter();
      formatter.printHelp("general options are: ", opts);
      return -1;
    }

    if (appIdStr == null) {
      System.out.println("ApplicationId cannot be null!");
      HelpFormatter formatter = new HelpFormatter();
      formatter.printHelp("general options are: ", opts);
      return -1;
    }

    RecordFactory recordFactory =
        RecordFactoryProvider.getRecordFactory(getConf());
    ApplicationId appId =
        ConverterUtils.toApplicationId(recordFactory, appIdStr);

    DataOutputStream out = new DataOutputStream(System.out);

    if (containerIdStr == null && nodeAddress == null) {
      dumpAllContainersLogs(appId, out);
    } else if ((containerIdStr == null && nodeAddress != null)
        || (containerIdStr != null && nodeAddress == null)) {
      System.out.println("ContainerId or NodeAddress cannot be null!");
      HelpFormatter formatter = new HelpFormatter();
      formatter.printHelp("general options are: ", opts);
      return -1;
    } else {
      Path remoteRootLogDir =
        new Path(getConf().get(NMConfig.REMOTE_USER_LOG_DIR,
            NMConfig.DEFAULT_REMOTE_APP_LOG_DIR));
      AggregatedLogFormat.LogReader reader =
          new AggregatedLogFormat.LogReader(getConf(),
              LogAggregationService.getRemoteNodeLogFileForApp(
                  remoteRootLogDir, appId, nodeAddress));
      return dumpAContainerLogs(containerIdStr, reader, out);
    }

    return 0;
  }

  private int dumpAContainerLogs(String containerIdStr,
      AggregatedLogFormat.LogReader reader, DataOutputStream out)
      throws IOException {
    DataInputStream valueStream;
    LogKey key = new LogKey();
    valueStream = reader.next(key);

    while (valueStream != null && !key.toString().equals(containerIdStr)) {
      // Next container
      key = new LogKey();
      valueStream = reader.next(key);
    }

    if (valueStream == null) {
      System.out.println("Logs for container " + containerIdStr
          + " are not present in this log-file.");
      return -1;
    }

    while (true) {
      try {
        LogReader.readAContainerLogsForALogType(valueStream, out);
      } catch (EOFException eof) {
        break;
      }
    }
    return 0;
  }

  private void
      dumpAllContainersLogs(ApplicationId appId, DataOutputStream out)
          throws IOException {
    Path remoteRootLogDir =
        new Path(getConf().get(NMConfig.REMOTE_USER_LOG_DIR,
            NMConfig.DEFAULT_REMOTE_APP_LOG_DIR));
    Path remoteAppLogDir =
        LogAggregationService.getRemoteAppLogDir(remoteRootLogDir, appId);
    RemoteIterator<FileStatus> nodeFiles =
        FileContext.getFileContext().listStatus(remoteAppLogDir);
    while (nodeFiles.hasNext()) {
      FileStatus thisNodeFile = nodeFiles.next();
      AggregatedLogFormat.LogReader reader =
          new AggregatedLogFormat.LogReader(getConf(),
              LogAggregationService.getRemoteNodeLogFileForApp(
                  remoteRootLogDir, appId, thisNodeFile.getPath().getName()));
      try {

        DataInputStream valueStream;
        LogKey key = new LogKey();
        valueStream = reader.next(key);

        while (valueStream != null) {
          while (true) {
            try {
              LogReader.readAContainerLogsForALogType(valueStream, out);
            } catch (EOFException eof) {
              break;
            }
          }

          // Next container
          key = new LogKey();
          valueStream = reader.next(key);
        }
      } finally {
        reader.close();
      }
    }
  }

  public static void main(String[] args) throws Exception {
    Configuration conf = new YarnConfiguration();
    LogDumper logDumper = new LogDumper();
    logDumper.setConf(conf);
    logDumper.run(args);
  }
}
