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

#pragma once

#include <iostream>
#include <optional>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <vector>

#include <glog/logging.h>
#include <rapidjson/document.h>

#include "kudu/gutil/strings/stringpiece.h"
#include "kudu/util/jsonreader.h" // IWYU pragma: keep
#include "kudu/util/status.h"

namespace kudu {

namespace tools {

// One of the record types from the log.
// TODO(KUDU-2353) support metrics records.
enum class RecordType {
  kSymbols,
  kStacks,
  kUnknown
};

const char* RecordTypeToString(RecordType r);

std::ostream& operator<<(std::ostream& o, RecordType r);

// A stack sample from the log.
struct StacksRecord {
  // A group of threads which share the same stack trace.
  struct Group {
    // The thread IDs in this group.
    std::vector<int> tids;
    // The non-symbolized addresses forming the stack trace.
    std::vector<std::string> frame_addrs;
  };

  // The time the stack traces were collected.
  std::string date_time;

  // The reason for stack trace collection.
  std::string reason;

  // The grouped threads with their stack traces.
  std::vector<Group> groups;
};

// Interface for consuming the parsed records from a diagnostics log.
class LogVisitor {
 public:
  virtual ~LogVisitor() {}
  virtual void VisitSymbol(const std::string& addr, const std::string& symbol) = 0;
  virtual void VisitStacksRecord(const StacksRecord& sr) = 0;
};

// LogVisitor implementation which dumps the parsed stack records to cout.
class StackDumpingLogVisitor : public LogVisitor {
 public:
  void VisitSymbol(const std::string& addr, const std::string& symbol) override;

  void VisitStacksRecord(const StacksRecord& sr) override;

 private:
  // True when we have not yet output any data.
  bool first_ = true;
  // Map from symbols to name.
  std::unordered_map<std::string, std::string> symbols_;

  const std::string kUnknownSymbol = "<unknown>";
};

// A parsed line from the diagnostics log.
//
// Each line contains a timestamp, a record type, and some JSON data.
class ParsedLine {
 public:
  // Parse a line from the diagnostics log.
  Status Parse(std::string line);

  RecordType type() const { return type_; }

  const rapidjson::Value* json() const {
    CHECK(json_);
    return json_->root();
  }

  std::string date_time() const;

 private:
  std::string line_;
  RecordType type_;

  // date_ and time_ point to substrings of line_.
  StringPiece date_;
  StringPiece time_;

  // A JsonReader initialized from the most recent line.
  // This will be 'none' before any lines have been read.
  std::optional<JsonReader> json_;
};

// Parser for a metrics log.
//
// Each line should be fed to LogParser::ParseLine().
//
// This instance follows a 'SAX' model. As records are available, the appropriate
// functions are invoked on the visitor provided in the constructor.
class LogParser {
 public:
  explicit LogParser(LogVisitor* visitor);

  // Parse the next line of the log. This function may invoke the appropriate
  // visitor functions zero or more times.
  Status ParseLine(std::string line);

 private:
  Status ParseSymbols(const ParsedLine& lf);

  static Status ParseStackGroup(const rapidjson::Value& group_json,
                                StacksRecord::Group* group);

  Status ParseStacks(const ParsedLine& lf);

  LogVisitor* visitor_;
};

} // namespace tools
} // namespace kudu
