// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/developer/debug/zxdb/console/commands/verb_status.h"

#include "lib/fit/defer.h"
#include "src/developer/debug/zxdb/client/remote_api.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/console/command.h"
#include "src/developer/debug/zxdb/console/console.h"
#include "src/developer/debug/zxdb/console/console_context.h"
#include "src/developer/debug/zxdb/console/format_filter.h"
#include "src/developer/debug/zxdb/console/format_job.h"
#include "src/developer/debug/zxdb/console/format_table.h"
#include "src/developer/debug/zxdb/console/format_target.h"
#include "src/developer/debug/zxdb/console/output_buffer.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace zxdb {

namespace {

const char kStatusShortHelp[] = "status: Show debugger status.";
const char kStatusHelp[] = R"(status: Show debugger status.

  Shows information on the current connection, process, thread, etc. along
  with suggestions on what to do.
)";

Err RunVerbStatus(ConsoleContext* context, const Command& cmd, CommandCallback cb = nullptr) {
  OutputBuffer out;
  out.Append(GetConnectionStatus(context->session()));
  out.Append("\n");

  if (!context->session()->IsConnected()) {
    Console::get()->Output(std::move(out));
    return Err();
  }

  out.Append(GetJobStatus(context));
  out.Append("\n");
  out.Append(GetFilterStatus(context));
  out.Append("\n");
  out.Append(GetProcessStatus(context));
  out.Append("\n");

  // Attempt to get the agent's state.
  context->session()->remote_api()->Status(
      {}, [out = std::move(out), session = context->session()->GetWeakPtr(), cb = std::move(cb)](
              const Err& err, debug_ipc::StatusReply reply) mutable {
        // Call the callback if applicable.
        Err return_err = err;
        auto defer = fit::defer([&return_err, cb = std::move(cb)]() mutable {
          if (cb)
            cb(return_err);
        });

        if (!session) {
          return_err = Err("No session found.");
          return;
        }

        if (err.has_error()) {
          return_err = err;
          return;
        }

        // Append the Limbo state.
        out.Append(GetLimboStatus(reply.limbo));

        Console::get()->Output(std::move(out));
      });

  return Err();
}

OutputBuffer FormatProcessRecords(std::vector<debug_ipc::ProcessRecord> records, int indent) {
  // Sort by name.
  std::sort(records.begin(), records.end(),
            [](const debug_ipc::ProcessRecord& lhs, const debug_ipc::ProcessRecord& rhs) {
              return lhs.process_name < rhs.process_name;
            });

  std::vector<std::vector<std::string>> rows;

  for (const debug_ipc::ProcessRecord& record : records) {
    auto& row = rows.emplace_back();
    row.reserve(4);

    row.push_back(std::to_string(record.process_koid));
    row.push_back(record.process_name);
  }

  OutputBuffer out;
  FormatTable({ColSpec(Align::kRight, 0, "Koid", indent), ColSpec(Align::kLeft, 0, "Name")}, rows,
              &out);

  return out;
}

}  // namespace

VerbRecord GetStatusVerbRecord() {
  return VerbRecord(&RunVerbStatus, {"status", "stat", "wtf"}, kStatusShortHelp, kStatusHelp,
                    CommandGroup::kGeneral);
}

OutputBuffer GetConnectionStatus(const Session* session) {
  OutputBuffer result;
  result.Append(Syntax::kHeading, "Connection\n");
  if (session->is_minidump()) {
    result.Append(Syntax::kHeading, "  Opened minidump: ");
    result.Append(session->minidump_path() + "\n");
  } else if (session->IsConnected()) {
    result.Append(fxl::StringPrintf("  Connected to '%s' on port %d.\n",
                                    session->connected_host().c_str(), session->connected_port()));
  } else {
    result.Append(
        "  Not connected. You can type these commands (see also \"help "
        "<command>\").\n\n");
    result.Append(Syntax::kHeading, "  connect");
    result.Append(R"( <host+port>
     Connects to a debug agent running on a remote system on the given port.
     However, most users will use a debug command from their environment to
     automatically run the debug_agent and connect the zxdb frontend to it
     (e.g. "ffx debug connect"). See your environment's documentation.

)");
    result.Append(Syntax::kHeading, "  opendump");
    result.Append(R"( <local filename>
    Opens a local file containing a crash dump for analysis.

)");
    result.Append(Syntax::kHeading, "  quit");
    result.Append(R"(
    Have a nice day.
)");
  }

  return result;
}

OutputBuffer GetFilterStatus(ConsoleContext* context) {
  OutputBuffer result;
  result.Append(Syntax::kHeading, "Process name filters\n");
  result.Append(
      "  Filters match the names of processes launched in attached jobs and\n"
      "  automatically attaches to them.\n");

  if (context->session()->system().GetFilters().empty()) {
    result.Append("\n  There are no filters. Use \"attach <process-name>\" to create one.\n");
  } else {
    result.Append(FormatFilterList(context, nullptr, 2));
  }

  return result;
}

OutputBuffer GetJobStatus(ConsoleContext* context) {
  OutputBuffer result;
  result.Append(Syntax::kHeading, "Jobs\n");

  auto jobs = context->session()->system().GetJobs();
  int attached_count = 0;
  for (const auto& j : jobs) {
    if (j->state() == Job::State::kAttached)
      attached_count++;
  }

  result.Append(
      fxl::StringPrintf("  Attached to %d job(s) (jobs are nodes in the Zircon process tree). "
                        "Processes\n  launched in attached jobs can be caught and debugged via "
                        "\"attach\" filters.\n  See \"help job\" and \"help attach\". The "
                        "debugger has these:\n",
                        attached_count));
  result.Append(FormatJobList(context, 2));

  return result;
}

OutputBuffer GetProcessStatus(ConsoleContext* context) {
  OutputBuffer result;
  result.Append(Syntax::kHeading, "Processes\n");

  auto targets = context->session()->system().GetTargets();
  int attached_count = 0;
  for (const auto& t : targets) {
    if (t->GetState() == Target::State::kRunning)
      attached_count++;
  }

  result.Append(
      fxl::StringPrintf("  Attached to %d process(es). The debugger has these:\n", attached_count));
  result.Append(FormatTargetList(context, 2));

  return result;
}

OutputBuffer GetLimboStatus(const std::vector<debug_ipc::ProcessRecord>& limbo) {
  OutputBuffer result;

  result.Append(Syntax::kHeading, "Processes waiting on exception\n");
  if (limbo.empty()) {
    result.Append("  No processes waiting on exception.");
  } else {
    result.Append(fxl::StringPrintf("  %zu process(es) waiting on exception. ", limbo.size()));
    result.Append(
        "Run \"attach <KOID>\" to load one into\n"
        "  zxdb or \"detach <KOID>\" to terminate them. See \"help jitd\" for more\n"
        "  information on Just-In-Time Debugging.\n");

    result.Append(FormatProcessRecords(limbo, 4));
  }

  return result;
}

}  // namespace zxdb
