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

#ifndef SRC_DEVELOPER_DEBUG_ZXDB_EXPR_EVAL_DWARF_EXPR_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_EXPR_EVAL_DWARF_EXPR_H_

#include <vector>

#include "src/developer/debug/zxdb/expr/eval_callback.h"
#include "src/developer/debug/zxdb/expr/expr_value.h"
#include "src/developer/debug/zxdb/symbols/dwarf_expr_eval.h"
#include "src/lib/fxl/memory/ref_counted.h"

// This file bridges the C++/Rust expression system and the symbol system's DwarfExprEval which does
// the low-level DWARF operation evaluation of DwarfExpr objects. In the simplest case you'll want
// to evaluate a DWARF expression and get an ExprValue out. In that case, use:
//
//  - DwarfExprToValue(...)
//
// There are some other uses that need more detailed control. Some code needs direct access to the
// DwarfExprEval. These cases should use one of the helper objects:
//
//  - If you want an ExprValue out but need to set up some initial state on the DwarfExprEval
//    before doing the evaluation, use AsyncDwarfExprEvalValue.
//
//  - If you want raw access to the DwarfExprEval both before and after evaluation, use
//    AsyncDwarfExprEval.

namespace zxdb {

class EvalContext;
class SymbolContext;
class Type;

// Evaluates the given DWARF expression and calls the callback with the result, using the given
// type. See file comment above.
void DwarfExprToValue(UnitSymbolFactory symbol_factory,
                      const fxl::RefPtr<EvalContext>& eval_context,
                      const SymbolContext& symbol_context, DwarfExpr expr, fxl::RefPtr<Type> type,
                      EvalCallback cb);

// Helper function which, given a completed DwarfExprEval, attempts to convert its result to the
// given type and executes the given callback.
void DwarfExprEvalToValue(const fxl::RefPtr<EvalContext>& context, DwarfExprEval& eval,
                          fxl::RefPtr<Type> type, EvalCallback cb);

// Manages evaluation of a DWARF expression (which might be asynchronous and need some tricky memory
// management). This keeps itself and the expression evaluator alive during the computation.
//
// See the file comment above, most callers will want one of the other variants.
//
// Example:
//
//   auto eval = fxl::MakeRefCounted<AsyncDwarfExprEval>([](DwarfExprEval& eval) {
//     eval->...();
//   });
//   eval->Eval(data_provider, expression);
//
class AsyncDwarfExprEval : public fxl::RefCountedThreadSafe<AsyncDwarfExprEval> {
 public:
  using DwarfEvalCallback = fit::callback<void(DwarfExprEval&, const Err& err)>;

  // Allows the expression evaluator to be set up before Eval() is called for cases where it needs
  // initial state.
  DwarfExprEval& dwarf_eval() { return dwarf_eval_; }

  // Starts evaluation. It will take a reference to itself during execution and the callback passed
  // into the constructor will be issued on completion. This can only be called once.
  //
  // The symbol context should be the one for the module the expression came from so that addresses
  // within the expression can be interpreted correctly.
  void Eval(DwarfExpr expr);

 protected:
  FRIEND_REF_COUNTED_THREAD_SAFE(AsyncDwarfExprEval);
  FRIEND_MAKE_REF_COUNTED(AsyncDwarfExprEval);

  explicit AsyncDwarfExprEval(UnitSymbolFactory symbol_factory,
                              fxl::RefPtr<SymbolDataProvider> data_provider,
                              const SymbolContext& expr_symbol_context, DwarfEvalCallback cb)
      : dwarf_eval_(std::move(symbol_factory), std::move(data_provider), expr_symbol_context),
        dwarf_callback_(std::move(cb)) {}
  virtual ~AsyncDwarfExprEval() = default;

 private:
  DwarfExprEval dwarf_eval_;
  DwarfEvalCallback dwarf_callback_;
};

// Automatically converts the result of the DwarfExprEval to an EvalCallback (an error or a value).
// See the simpler DwarfExprToValue() function above for cases that don't need low-level access to
// the DwarfExprEval object.
//
// Example:
//
//   auto eval = fxl::MakeRefCounted<AsyncDwarfExprEvalValue>(context, type, std::move(cb));
//   ...any required setup of the dwarf_eval()...
//   eval->Eval(context->GetDataProvider(), expression);
//
class AsyncDwarfExprEvalValue : public AsyncDwarfExprEval {
 public:
  // Call Eval() on the base class to start evaluation.

 protected:
  FRIEND_REF_COUNTED_THREAD_SAFE(AsyncDwarfExprEvalValue);
  FRIEND_MAKE_REF_COUNTED(AsyncDwarfExprEvalValue);

  // The passed-in callback will be executed if the DwarfExprEval returns success. It will have
  // the given type.
  AsyncDwarfExprEvalValue(UnitSymbolFactory symbol_factory,
                          fxl::RefPtr<SymbolDataProvider> data_provider,
                          const SymbolContext& expr_symbol_context,
                          const fxl::RefPtr<EvalContext>& context, fxl::RefPtr<Type> type,
                          EvalCallback cb);

 private:
  void OnEvalComplete(const Err& err);

  fxl::RefPtr<EvalContext> context_;

  // Not necessarily a concrete type, this is the type of the result the user will see.
  fxl::RefPtr<Type> type_;

  EvalCallback value_callback_;
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_EXPR_EVAL_DWARF_EXPR_H_
