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

#ifndef SRC_DEVELOPER_DEBUG_ZXDB_EXPR_EVAL_CONTEXT_IMPL_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_EXPR_EVAL_CONTEXT_IMPL_H_

#include <optional>
#include <vector>

#include "src/developer/debug/zxdb/expr/eval_context.h"
#include "src/developer/debug/zxdb/expr/found_name.h"
#include "src/developer/debug/zxdb/expr/pretty_type_manager.h"
#include "src/developer/debug/zxdb/symbols/symbol.h"
#include "src/developer/debug/zxdb/symbols/symbol_context.h"
#include "src/lib/fxl/memory/weak_ptr.h"

namespace zxdb {

class CodeBlock;
class DwarfExprEval;
class LazySymbol;
class Location;
class ProcessSymbols;
class SymbolDataProvider;
class Variable;

// An implementation of EvalContext that integrates with the DWARF symbol system. It will provide
// the values of variables currently in scope.
//
// This object is reference counted since it requires asynchronous operations in some cases. This
// means it can outlive the scope in which it was invoked (say if the thread was resumed or the
// process was killed).
//
// Generally the creator of this context will be something representing that context in the running
// program like a stack frame. This frame should call DisownContext() when it is destroyed to ensure
// that evaluation does not use any invalid context.
class EvalContextImpl : public EvalContext {
 public:
  // Construct with fxl::MakeRefCounted.

  // EvalContext implementation.
  //
  // NOTE: Some of these implementations return constant values because the expression library
  // doesn't have enough context to know what they should be. The ClientEvalContextImpl hooks
  // some things up to the debugger settings system.
  ExprLanguage GetLanguage() const override;
  const std::shared_ptr<Abi>& GetAbi() const override { return abi_; }
  FindNameContext GetFindNameContext() const override;
  void GetNamedValue(const ParsedIdentifier& name, EvalCallback cb) const override;
  void GetVariableValue(fxl::RefPtr<Value> variable, EvalCallback cb) const override;
  const ProcessSymbols* GetProcessSymbols() const override;
  fxl::RefPtr<SymbolDataProvider> GetDataProvider() override;
  NameLookupCallback GetSymbolNameLookupCallback() override;
  Location GetLocationForAddress(uint64_t address) const override;
  const PrettyTypeManager& GetPrettyTypeManager() const override { return pretty_type_manager_; }
  VectorRegisterFormat GetVectorRegisterFormat() const override {
    return VectorRegisterFormat::kDouble;
  }
  bool ShouldPromoteToDerived() const override { return false; }

 protected:
  FRIEND_REF_COUNTED_THREAD_SAFE(EvalContextImpl);
  FRIEND_MAKE_REF_COUNTED(EvalContextImpl);

  // All of the input pointers can be null:
  //
  //  - The ProcessSymbols can be a null weak pointer in which case globals will not be resolved.
  //    This can make testing easier and supports evaluating math without a loaded program.
  //
  //  - The SymbolDataProvider can be null in which case anything that requires memory from the
  //    target will fail. Some operations like pure math don't require this.
  //
  //  - The code block can be null in which case nothing using the current scope will work. This
  //    includes local variables, variables on "this", and things relative to the current namespace.
  //
  // The variant that takes a location will extract the code block from the location if possible.
  EvalContextImpl(std::shared_ptr<Abi> abi, fxl::WeakPtr<const ProcessSymbols> process_symbols,
                  fxl::RefPtr<SymbolDataProvider> data_provider, ExprLanguage language,
                  fxl::RefPtr<CodeBlock> code_block = fxl::RefPtr<CodeBlock>());
  EvalContextImpl(std::shared_ptr<Abi> abi, fxl::WeakPtr<const ProcessSymbols> process_symbols,
                  fxl::RefPtr<SymbolDataProvider> data_provider, const Location& location,
                  std::optional<ExprLanguage> force_language = std::nullopt);
  ~EvalContextImpl() override;

 private:
  // Converts an extern value to a real Variable by looking the name up in the index.
  Err ResolveExternValue(const fxl::RefPtr<Value>& input_value,
                         fxl::RefPtr<Variable>* resolved) const;

  // Computes the value of the given variable and issues the callback (possibly asynchronously,
  // possibly not).
  void DoResolve(FoundName found, EvalCallback cb) const;

  // Implements type name lookup on the target's symbol index.
  FoundName DoTargetSymbolsNameLookup(const ParsedIdentifier& ident);

  std::shared_ptr<Abi> abi_;

  fxl::WeakPtr<const ProcessSymbols> process_symbols_;  // Possibly null.
  fxl::RefPtr<SymbolDataProvider> data_provider_;       // Possibly null.

  // Innermost block of the current context. May be null if there is none (this means you won't get
  // any local variable lookups).
  fxl::RefPtr<const CodeBlock> block_;

  // Language extracted from the code block.
  ExprLanguage language_ = ExprLanguage::kC;

  PrettyTypeManager pretty_type_manager_;

  mutable fxl::WeakPtrFactory<EvalContextImpl> weak_factory_;
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_EXPR_EVAL_CONTEXT_IMPL_H_
