// 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/client/breakpoint.h"

#include "src/developer/debug/zxdb/client/setting_schema.h"
#include "src/developer/debug/zxdb/client/setting_schema_definition.h"
#include "src/lib/fxl/logging.h"

namespace zxdb {

const char* ClientSettings::Breakpoint::kLocation = "location";
const char* ClientSettings::Breakpoint::kLocationDescription =
    R"(  The location (symbol, line number, address, or expression) where this
  breakpoint will be set. See "help break" for documentation on how to specify.)";

const char* ClientSettings::Breakpoint::kScope = "scope";
const char* ClientSettings::Breakpoint::kScopeDescription =
    R"(  What this breakpoint applies to. Examples:

    global:     All processes (the default).
    "pr 3":     All threads in a process 3.
    "pr 3 t 2": Only thread 2 of process 3.)";

const char* ClientSettings::Breakpoint::kEnabled = "enabled";
const char* ClientSettings::Breakpoint::kEnabledDescription =
    R"(  Whether this breakpoint is enabled. Disabled breakpoints keep their settings
  but are not installed and will not stop or increment their hit count.)";

const char* ClientSettings::Breakpoint::kOneShot = "one-shot";
const char* ClientSettings::Breakpoint::kOneShotDescription =
    R"(  Whether this breakpoint is one-shot. One-shot breakpoints are automatically
  deleted when hit.)";

const char* ClientSettings::Breakpoint::kType = "type";
const char* ClientSettings::Breakpoint::kTypeDescription =
    "  Type of breakpoint. Possible values are:\n\n" BREAKPOINT_TYPE_HELP("    ");

const char* ClientSettings::Breakpoint::kType_Software = "software";
const char* ClientSettings::Breakpoint::kType_Hardware = "execute";
const char* ClientSettings::Breakpoint::kType_ReadWrite = "read-write";
const char* ClientSettings::Breakpoint::kType_Write = "write";

const char* ClientSettings::Breakpoint::kStopMode = "stop";
const char* ClientSettings::Breakpoint::kStopModeDescription =
    R"(  What to stop when this breakpoint is hit. Possible values are:

  none
      Do not stop anything when this breakpoint is hit. The breakpoint will
      still be installed and will still accumulate hit counts.

  thread
      Stop only the thread that hit the breakpoint. Other threads in the same
      process and other processes will be unaffected.

  process
      Stop all threads in the process that hit the breakpoint. Other processes
      being debugged will be unaffected.

  all
      Stop all processes currently being debugged.)";
const char* ClientSettings::Breakpoint::kStopMode_None = "none";
const char* ClientSettings::Breakpoint::kStopMode_Thread = "thread";
const char* ClientSettings::Breakpoint::kStopMode_Process = "process";
const char* ClientSettings::Breakpoint::kStopMode_All = "all";

namespace {

fxl::RefPtr<SettingSchema> CreateSchema() {
  auto schema = fxl::MakeRefCounted<SettingSchema>();
  schema->AddInputLocations(ClientSettings::Breakpoint::kLocation,
                            ClientSettings::Breakpoint::kLocationDescription);
  schema->AddExecutionScope(ClientSettings::Breakpoint::kScope,
                            ClientSettings::Breakpoint::kScopeDescription);
  schema->AddBool(ClientSettings::Breakpoint::kEnabled,
                  ClientSettings::Breakpoint::kEnabledDescription, true);
  schema->AddBool(ClientSettings::Breakpoint::kOneShot,
                  ClientSettings::Breakpoint::kOneShotDescription, false);
  schema->AddString(
      ClientSettings::Breakpoint::kType, ClientSettings::Breakpoint::kTypeDescription,
      ClientSettings::Breakpoint::kType_Software,
      {ClientSettings::Breakpoint::kType_Software, ClientSettings::Breakpoint::kType_Hardware,
       ClientSettings::Breakpoint::kType_ReadWrite, ClientSettings::Breakpoint::kType_Write});
  schema->AddString(
      ClientSettings::Breakpoint::kStopMode, ClientSettings::Breakpoint::kStopModeDescription,
      ClientSettings::Breakpoint::kStopMode_All,
      {ClientSettings::Breakpoint::kStopMode_None, ClientSettings::Breakpoint::kStopMode_Thread,
       ClientSettings::Breakpoint::kStopMode_Process, ClientSettings::Breakpoint::kStopMode_All});
  return schema;
}

}  // namespace

Breakpoint::Settings::Settings(Breakpoint* bp) : SettingStore(Breakpoint::GetSchema()), bp_(bp) {}

SettingValue Breakpoint::Settings::GetStorageValue(const std::string& key) const {
  BreakpointSettings settings = bp_->GetSettings();
  if (key == ClientSettings::Breakpoint::kLocation) {
    return SettingValue(settings.locations);
  } else if (key == ClientSettings::Breakpoint::kScope) {
    return SettingValue(settings.scope);
  } else if (key == ClientSettings::Breakpoint::kStopMode) {
    return SettingValue(BreakpointSettings::StopModeToString(settings.stop_mode));
  } else if (key == ClientSettings::Breakpoint::kEnabled) {
    return SettingValue(settings.enabled);
  } else if (key == ClientSettings::Breakpoint::kOneShot) {
    return SettingValue(settings.one_shot);
  } else if (key == ClientSettings::Breakpoint::kType) {
    return SettingValue(BreakpointSettings::TypeToString(settings.type));
  }
  FXL_NOTREACHED();
  return SettingValue();
}

Err Breakpoint::Settings::SetStorageValue(const std::string& key, SettingValue value) {
  BreakpointSettings settings = bp_->GetSettings();

  if (key == ClientSettings::Breakpoint::kLocation) {
    settings.locations = value.get_input_locations();
  } else if (key == ClientSettings::Breakpoint::kScope) {
    settings.scope = value.get_execution_scope();
  } else if (key == ClientSettings::Breakpoint::kStopMode) {
    std::optional<BreakpointSettings::StopMode> stop_mode =
        BreakpointSettings::StringToStopMode(value.get_string());
    FXL_DCHECK(stop_mode);  // Schema should have validated the input.
    settings.stop_mode = *stop_mode;
  } else if (key == ClientSettings::Breakpoint::kEnabled) {
    settings.enabled = value.get_bool();
  } else if (key == ClientSettings::Breakpoint::kOneShot) {
    settings.one_shot = value.get_bool();
  } else if (key == ClientSettings::Breakpoint::kType) {
    std::optional<BreakpointSettings::Type> type =
        BreakpointSettings::StringToType(value.get_string());
    FXL_DCHECK(type);  // Schema should have validated the input.
    settings.type = *type;
  } else {
    FXL_NOTREACHED();
  }

  // This code doesn't have a good way to communicate breakpoint set failures from this location.
  // TODO(brettw) we may need a notification that the frontend can listen for and display.
  bp_->SetSettings(settings, [](const Err&) {});
  return Err();
}

Breakpoint::Breakpoint(Session* session)
    : ClientObject(session), settings_(this), weak_factory_(this) {}
Breakpoint::~Breakpoint() {}

fxl::WeakPtr<Breakpoint> Breakpoint::GetWeakPtr() { return weak_factory_.GetWeakPtr(); }

// static
fxl::RefPtr<SettingSchema> Breakpoint::GetSchema() {
  static fxl::RefPtr<SettingSchema> schema = CreateSchema();
  return schema;
}

}  // namespace zxdb
