// 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.

#include "util/summary-util.h"

#include <vector>
#include <boost/lexical_cast.hpp>

#include "common/logging.h"
#include "util/pretty-printer.h"
#include "util/redactor.h"
#include "util/table-printer.h"

#include "common/names.h"

using namespace impala;

// Helper function for PrintExecSummary() that walks the exec summary recursively.
// Output for this node is appended to *result. Each value in *result should contain
// the statistics for a single exec summary node.
// node_idx is an in/out parameter. It is called with the idx (into exec_summary_.nodes)
// for the current node and on return, will contain the id of the next node.
void PrintExecSummary(const TExecSummary& exec_summary, int indent_level,
    int new_indent_level, int* node_idx,
    vector<vector<string>>* result) {
  DCHECK_LT(*node_idx, exec_summary.nodes.size());
  const TPlanNodeExecSummary& node = exec_summary.nodes[*node_idx];
  const TExecStats& est_stats = node.estimated_stats;

  TExecStats agg_stats;
  TExecStats max_stats;

#define COMPUTE_MAX_SUM_STATS(NAME)\
  agg_stats.NAME += node.exec_stats[i].NAME;\
  max_stats.NAME = std::max(max_stats.NAME, node.exec_stats[i].NAME)

  // Compute avg and max of each used stat (cpu_time_ns is unused in the summary output).
  for (int i = 0; i < node.exec_stats.size(); ++i) {
    COMPUTE_MAX_SUM_STATS(latency_ns);
    COMPUTE_MAX_SUM_STATS(cardinality);
    COMPUTE_MAX_SUM_STATS(memory_used);
  }
#undef COMPUTE_MAX_SUM_STATS

  int64_t avg_time = node.exec_stats.size() == 0 ? 0 :
      agg_stats.latency_ns / node.exec_stats.size();

  // Print the level to indicate nesting with "|--"
  stringstream label_ss;
  if (indent_level != 0) {
    label_ss << "|";
    for (int i = 0; i < indent_level - 1; ++i) {
      label_ss << "  |";
    }
    label_ss << (new_indent_level ? "--" : "  ");
  }

  label_ss << node.label;

  vector<string> row;
  row.push_back(label_ss.str());
  row.push_back(lexical_cast<string>(node.exec_stats.size())); // Num instances
  row.push_back(PrettyPrinter::Print(avg_time, TUnit::TIME_NS));
  row.push_back(PrettyPrinter::Print(max_stats.latency_ns, TUnit::TIME_NS));
  row.push_back(PrettyPrinter::Print(
      node.is_broadcast ? max_stats.cardinality : agg_stats.cardinality,
      TUnit::UNIT));
  row.push_back(PrettyPrinter::Print(est_stats.cardinality, TUnit::UNIT));
  row.push_back(PrettyPrinter::Print(max_stats.memory_used, TUnit::BYTES));
  row.push_back(PrettyPrinter::Print(est_stats.memory_used, TUnit::BYTES));
  // Node "details" may contain exprs which should be redacted.
  row.push_back(RedactCopy(node.label_detail));
  result->push_back(row);

  map<int, int>::const_iterator child_fragment_idx_it =
      exec_summary.exch_to_sender_map.find(*node_idx);
  if (child_fragment_idx_it != exec_summary.exch_to_sender_map.end()) {
    DCHECK_EQ(node.num_children, 0);
    int child_fragment_id = child_fragment_idx_it->second;
    PrintExecSummary(exec_summary, indent_level, false, &child_fragment_id, result);
  }
  ++*node_idx;
  if (node.num_children == 0) return;

  // Print the non-left children to the stream first.
  vector<vector<string>> child0_result;
  PrintExecSummary(exec_summary, indent_level, false, node_idx, &child0_result);

  for (int i = 1; i < node.num_children; ++i) {
    PrintExecSummary(exec_summary, indent_level + 1, true, node_idx, result);
  }
  for (int i = 0; i < child0_result.size(); ++i) {
    result->push_back(child0_result[i]);
  }
}

string impala::PrintExecSummary(const TExecSummary& exec_summary) {
  // Bail if Coordinator::InitExecProfile() has not been called.
  if (!exec_summary.__isset.nodes) return "";

  TablePrinter printer;
  printer.set_max_output_width(1000);
  printer.AddColumn("Operator", true);
  printer.AddColumn("#Hosts", false);
  printer.AddColumn("Avg Time", false);
  printer.AddColumn("Max Time", false);
  printer.AddColumn("#Rows", false);
  printer.AddColumn("Est. #Rows", false);
  printer.AddColumn("Peak Mem", false);
  printer.AddColumn("Est. Peak Mem", false);
  printer.AddColumn("Detail", true);

  vector<vector<string>> rows;
  int node_idx = 0;
  ::PrintExecSummary(exec_summary, 0, false, &node_idx, &rows);
  for (int i = 0; i < rows.size(); ++i) {
    printer.AddRow(rows[i]);
  }
  return printer.ToString("\n");
}
