// Copyright 2018 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/format_frame.h"

#include <gtest/gtest.h>

#include "src/developer/debug/shared/platform_message_loop.h"
#include "src/developer/debug/zxdb/client/mock_frame.h"
#include "src/developer/debug/zxdb/client/mock_stack_delegate.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/stack.h"
#include "src/developer/debug/zxdb/client/thread.h"
#include "src/developer/debug/zxdb/console/async_output_buffer_test_util.h"
#include "src/developer/debug/zxdb/console/command_utils.h"
#include "src/developer/debug/zxdb/console/console_test.h"
#include "src/developer/debug/zxdb/console/format_location.h"
#include "src/developer/debug/zxdb/console/format_node_console.h"
#include "src/developer/debug/zxdb/console/output_buffer.h"
#include "src/developer/debug/zxdb/symbols/function.h"
#include "src/developer/debug/zxdb/symbols/location.h"
#include "src/developer/debug/zxdb/symbols/symbol_context.h"

namespace zxdb {

namespace {

class FormatFrameTest : public ConsoleTest {
 public:
  // Synchronous wrappers around asynchronous formatting.
  std::string SyncFormatStack(Thread* thread, const FormatStackOptions& opts) {
    return LoopUntilAsyncOutputBufferComplete(FormatStack(thread, false, opts)).AsString();
  }
  std::string SyncFormatFrame(const Frame* frame, const FormatFrameOptions& opts, int id = -1) {
    return LoopUntilAsyncOutputBufferComplete(FormatFrame(frame, opts, id)).AsString();
  }
};

}  // namespace

TEST_F(FormatFrameTest, FormatStack) {
  Stack& stack = thread()->GetStack();

  std::vector<std::unique_ptr<Frame>> frames;
  frames.push_back(std::make_unique<MockFrame>(nullptr, nullptr, 0x1001, 0x2001, "Function0",
                                               FileLine("file0.cc", 20)));
  frames.push_back(std::make_unique<MockFrame>(nullptr, nullptr, 0x1002, 0x2002, "Function1",
                                               FileLine("file1.cc", 21)));
  frames.push_back(std::make_unique<MockFrame>(nullptr, nullptr, 0x1003, 0x2003, "Function2",
                                               FileLine("file2.cc", 22)));
  frames.push_back(std::make_unique<MockFrame>(nullptr, nullptr, 0x1004, 0x2004, "Function3",
                                               FileLine("file3.cc", 23)));

  stack.SetFramesForTest(std::move(frames), true);

  FormatStackOptions opts;

  // No pretty formatting.
  EXPECT_EQ(
      "▶ 0 Function0() • file0.cc:20\n"
      "  1 Function1() • file1.cc:21\n"
      "  2 Function2() • file2.cc:22\n"
      "  3 Function3() • file3.cc:23\n",
      SyncFormatStack(thread(), opts));

  // Set up a PrettyStackManager to collapse the first two frames.
  auto manager = fxl::MakeRefCounted<PrettyStackManager>();
  std::vector<PrettyStackManager::StackGlob> matchers;
  matchers.push_back(PrettyStackManager::StackGlob(
      "Function0/1 Matcher",
      {PrettyFrameGlob::Func("Function0"), PrettyFrameGlob::Func("Function1")}));
  manager->SetMatchers(matchers);
  opts.pretty_stack = manager;

  // With pretty eliding of the first two frames.
  EXPECT_EQ(
      "▶ 0…1 «Function0/1 Matcher» (-r expands)\n"
      "  2 Function2() • file2.cc:22\n"
      "  3 Function3() • file3.cc:23\n",
      SyncFormatStack(thread(), opts));

  // Set the active frame to be frame 1. The matcher should no longer apply so the frame can be
  // shown.
  console().context().SetActiveFrameIdForThread(thread(), 1);
  EXPECT_EQ(
      "  0 Function0() • file0.cc:20\n"
      "▶ 1 Function1() • file1.cc:21\n"
      "  2 Function2() • file2.cc:22\n"
      "  3 Function3() • file3.cc:23\n",
      SyncFormatStack(thread(), opts));
}

TEST_F(FormatFrameTest, Unsymbolized) {
  MockFrame frame(nullptr, nullptr, Location(Location::State::kSymbolized, 0x12345678), 0x567890, 0,
                  std::vector<debug_ipc::Register>(), 0xdeadbeef);

  // Short format just prints the address.
  FormatFrameOptions simple_opts;
  simple_opts.detail = FormatFrameOptions::kSimple;
  EXPECT_EQ("0x12345678", SyncFormatFrame(&frame, simple_opts));

  // Long version should do the same.
  FormatFrameOptions verbose_opts;
  verbose_opts.detail = FormatFrameOptions::kVerbose;
  EXPECT_EQ("0x12345678\n      IP = 0x12345678, SP = 0x567890, base = 0xdeadbeef",
            SyncFormatFrame(&frame, verbose_opts));

  // Simple, with index.
  EXPECT_EQ("Frame 3 0x12345678", SyncFormatFrame(&frame, simple_opts, 3));
}

TEST_F(FormatFrameTest, Inline) {
  // This is to have some place for the inline frame to refer to as the underlying physical frame.
  // The values are ignored.
  MockFrame physical_frame(nullptr, nullptr, Location(Location::State::kSymbolized, 0x12345678),
                           0x567890);

  SymbolContext symbol_context = SymbolContext::ForRelativeAddresses();

  auto function = fxl::MakeRefCounted<Function>(DwarfTag::kInlinedSubroutine);
  function->set_assigned_name("Function");

  MockFrame inline_frame(
      nullptr, nullptr, Location(0x12345678, FileLine("file.cc", 22), 0, symbol_context, function),
      0x567890, 0, std::vector<debug_ipc::Register>(), 0xdeadbeef, &physical_frame);

  FormatFrameOptions simple_opts;
  simple_opts.detail = FormatFrameOptions::kSimple;
  EXPECT_EQ("Function() • file.cc:22 (inline)", SyncFormatFrame(&inline_frame, simple_opts));

  FormatFrameOptions param_opts;
  param_opts.detail = FormatFrameOptions::kParameters;
  EXPECT_EQ("Function() • file.cc:22 (inline)", SyncFormatFrame(&inline_frame, param_opts));

  FormatFrameOptions verbose_opts;
  verbose_opts.detail = FormatFrameOptions::kVerbose;
  EXPECT_EQ(
      "Function() • file.cc:22 (inline)\n"
      "      IP = 0x12345678, SP = 0x567890, base = 0xdeadbeef",
      SyncFormatFrame(&inline_frame, verbose_opts));
}

}  // namespace zxdb
