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

#pragma once

#include <string>
#include <vector>

#include <zircon/types.h>

#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/strings/string_view.h"

namespace debugserver {

class Server;
class Thread;

// Utility class for holding the thread action list argument to vCont packets.
// https://sourceware.org/gdb/current/onlinedocs/gdb/Packets.html

class ThreadActionList final {
 public:
  // The kind of action to perform.
  enum class Action {
    // No action specified for this thread.
    kNone,
    // Continue the thread.
    kContinue,
    // Step the thread one instruction.
    kStep,
    // Other actions are not supported yet.
  };

  // Utility class to hold one entry in ThreadActionList.
  class Entry final {
   public:
    Entry(Action action, zx_koid_t pid, zx_koid_t tid);
    ~Entry() = default;

    Action action() const { return action_; }
    zx_koid_t pid() const { return pid_; }
    zx_koid_t tid() const { return tid_; }

    // Call this to upgrade a "pick one" entry (tid == 0) to the chosen value.
    void set_picked_tid(zx_koid_t tid);

    bool Contains(zx_koid_t pid, zx_koid_t tid) const;

   private:
    friend class ThreadActionList;
    Action action_;
    // N.B. While the remote protocol defines zero for pid/tid to mean "pick a
    // random one" zero values do not end up in |pid_|. The "pick one" must be
    // done before an Entry is created. The "pick one" for |tid_| is resolved
    // later though, after the Entry is created.
    zx_koid_t pid_;
    zx_koid_t tid_;
  };

  // For pid,tid values, means "all processes" or "all threads".
  // TODO(dje): This is a legitimate value, we "should" use a different value,
  // but this is fine for now. The kernel reserves the first 1K, possibly we
  // could use one of those.
  static constexpr zx_koid_t kAll = ~0ull;

  static bool DecodeAction(char c, Action* out_action);

  static const char* ActionToString(Action action);

  ThreadActionList(const fxl::StringView& str, zx_koid_t cur_proc);

  ~ThreadActionList() = default;

  bool valid() const { return valid_; }

  // Call this after resolving all zero tid values, which means to "pick one".
  // This must be called before calling GetAction.
  // This exists to force caller to resolve zero tids ("pick one") to keep
  // the resolution code separate. That step may need to evolve. Plus we'd
  // have to stub out the resolution code in the unittest. Later.
  void MarkPickOnesResolved() { pick_ones_resolved_ = true; }

  // Return the action for |thread|.
  Action GetAction(zx_koid_t pid, zx_koid_t tid) const;

  Action default_action() const { return default_action_; }
  const std::vector<Entry>& actions() const { return actions_; }

 private:
  ThreadActionList() = default;

  // True if the contents are valid.
  bool valid_ = false;

  // True if "pick one" tid values have been resolved.
  bool pick_ones_resolved_ = false;

  Action default_action_ = Action::kNone;
  std::vector<Entry> actions_;

  FXL_DISALLOW_COPY_AND_ASSIGN(ThreadActionList);
};

}  // namespace debugserver
