//===-- TypeSynthetic.h -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_DATAFORMATTERS_TYPESYNTHETIC_H
#define LLDB_DATAFORMATTERS_TYPESYNTHETIC_H

#include <cstdint>

#include <functional>
#include <initializer_list>
#include <memory>
#include <string>
#include <vector>

#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-public.h"

#include "lldb/Core/ValueObject.h"
#include "lldb/Utility/StructuredData.h"

namespace lldb_private {
class SyntheticChildrenFrontEnd {
protected:
  ValueObject &m_backend;

  void SetValid(bool valid) { m_valid = valid; }

  bool IsValid() { return m_valid; }

public:
  SyntheticChildrenFrontEnd(ValueObject &backend)
      : m_backend(backend), m_valid(true) {}

  virtual ~SyntheticChildrenFrontEnd() = default;

  virtual size_t CalculateNumChildren() = 0;

  virtual size_t CalculateNumChildren(uint32_t max) {
    auto count = CalculateNumChildren();
    return count <= max ? count : max;
  }

  virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx) = 0;

  virtual size_t GetIndexOfChildWithName(ConstString name) = 0;

  // this function is assumed to always succeed and it if fails, the front-end
  // should know to deal with it in the correct way (most probably, by refusing
  // to return any children) the return value of Update() should actually be
  // interpreted as "ValueObjectSyntheticFilter cache is good/bad" if =true,
  // ValueObjectSyntheticFilter is allowed to use the children it fetched
  // previously and cached if =false, ValueObjectSyntheticFilter must throw
  // away its cache, and query again for children
  virtual bool Update() = 0;

  // if this function returns false, then CalculateNumChildren() MUST return 0
  // since UI frontends might validly decide not to inquire for children given
  // a false return value from this call if it returns true, then
  // CalculateNumChildren() can return any number >= 0 (0 being valid) it
  // should if at all possible be more efficient than CalculateNumChildren()
  virtual bool MightHaveChildren() = 0;

  // if this function returns a non-null ValueObject, then the returned
  // ValueObject will stand for this ValueObject whenever a "value" request is
  // made to this ValueObject
  virtual lldb::ValueObjectSP GetSyntheticValue() { return nullptr; }

  // if this function returns a non-empty ConstString, then clients are
  // expected to use the return as the name of the type of this ValueObject for
  // display purposes
  virtual ConstString GetSyntheticTypeName() { return ConstString(); }

  typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
  typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;

protected:
  lldb::ValueObjectSP
  CreateValueObjectFromExpression(llvm::StringRef name,
                                  llvm::StringRef expression,
                                  const ExecutionContext &exe_ctx);

  lldb::ValueObjectSP
  CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
                               const ExecutionContext &exe_ctx,
                               CompilerType type);

  lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name,
                                                const DataExtractor &data,
                                                const ExecutionContext &exe_ctx,
                                                CompilerType type);

private:
  bool m_valid;
  SyntheticChildrenFrontEnd(const SyntheticChildrenFrontEnd &) = delete;
  const SyntheticChildrenFrontEnd &
  operator=(const SyntheticChildrenFrontEnd &) = delete;
};

class SyntheticValueProviderFrontEnd : public SyntheticChildrenFrontEnd {
public:
  SyntheticValueProviderFrontEnd(ValueObject &backend)
      : SyntheticChildrenFrontEnd(backend) {}

  ~SyntheticValueProviderFrontEnd() override = default;

  size_t CalculateNumChildren() override { return 0; }

  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { return nullptr; }

  size_t GetIndexOfChildWithName(ConstString name) override {
    return UINT32_MAX;
  }

  bool Update() override { return false; }

  bool MightHaveChildren() override { return false; }

  lldb::ValueObjectSP GetSyntheticValue() override = 0;

private:
  SyntheticValueProviderFrontEnd(const SyntheticValueProviderFrontEnd &) =
      delete;
  const SyntheticValueProviderFrontEnd &
  operator=(const SyntheticValueProviderFrontEnd &) = delete;
};

class SyntheticChildren {
public:
  class Flags {
  public:
    Flags() = default;

    Flags(const Flags &other) : m_flags(other.m_flags) {}

    Flags(uint32_t value) : m_flags(value) {}

    Flags &operator=(const Flags &rhs) {
      if (&rhs != this)
        m_flags = rhs.m_flags;

      return *this;
    }

    Flags &operator=(const uint32_t &rhs) {
      m_flags = rhs;
      return *this;
    }

    Flags &Clear() {
      m_flags = 0;
      return *this;
    }

    bool GetCascades() const {
      return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
    }

    Flags &SetCascades(bool value = true) {
      if (value)
        m_flags |= lldb::eTypeOptionCascade;
      else
        m_flags &= ~lldb::eTypeOptionCascade;
      return *this;
    }

    bool GetSkipPointers() const {
      return (m_flags & lldb::eTypeOptionSkipPointers) ==
             lldb::eTypeOptionSkipPointers;
    }

    Flags &SetSkipPointers(bool value = true) {
      if (value)
        m_flags |= lldb::eTypeOptionSkipPointers;
      else
        m_flags &= ~lldb::eTypeOptionSkipPointers;
      return *this;
    }

    bool GetSkipReferences() const {
      return (m_flags & lldb::eTypeOptionSkipReferences) ==
             lldb::eTypeOptionSkipReferences;
    }

    Flags &SetSkipReferences(bool value = true) {
      if (value)
        m_flags |= lldb::eTypeOptionSkipReferences;
      else
        m_flags &= ~lldb::eTypeOptionSkipReferences;
      return *this;
    }

    bool GetNonCacheable() const {
      return (m_flags & lldb::eTypeOptionNonCacheable) ==
             lldb::eTypeOptionNonCacheable;
    }

    Flags &SetNonCacheable(bool value = true) {
      if (value)
        m_flags |= lldb::eTypeOptionNonCacheable;
      else
        m_flags &= ~lldb::eTypeOptionNonCacheable;
      return *this;
    }

    bool GetFrontEndWantsDereference() const {
      return (m_flags & lldb::eTypeOptionFrontEndWantsDereference) ==
             lldb::eTypeOptionFrontEndWantsDereference;
    }

    Flags &SetFrontEndWantsDereference(bool value = true) {
      if (value)
        m_flags |= lldb::eTypeOptionFrontEndWantsDereference;
      else
        m_flags &= ~lldb::eTypeOptionFrontEndWantsDereference;
      return *this;
    }

    uint32_t GetValue() { return m_flags; }

    void SetValue(uint32_t value) { m_flags = value; }

  private:
    uint32_t m_flags = lldb::eTypeOptionCascade;
  };

  SyntheticChildren(const Flags &flags) : m_flags(flags) {}

  virtual ~SyntheticChildren() = default;

  bool Cascades() const { return m_flags.GetCascades(); }

  bool SkipsPointers() const { return m_flags.GetSkipPointers(); }

  bool SkipsReferences() const { return m_flags.GetSkipReferences(); }

  bool NonCacheable() const { return m_flags.GetNonCacheable(); }
  
  bool WantsDereference() const { return m_flags.GetFrontEndWantsDereference();} 

  void SetCascades(bool value) { m_flags.SetCascades(value); }

  void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); }

  void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); }

  void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); }

  uint32_t GetOptions() { return m_flags.GetValue(); }

  void SetOptions(uint32_t value) { m_flags.SetValue(value); }

  virtual bool IsScripted() = 0;

  virtual std::string GetDescription() = 0;

  virtual SyntheticChildrenFrontEnd::AutoPointer
  GetFrontEnd(ValueObject &backend) = 0;

  typedef std::shared_ptr<SyntheticChildren> SharedPointer;

  uint32_t &GetRevision() { return m_my_revision; }

protected:
  uint32_t m_my_revision;
  Flags m_flags;

private:
  SyntheticChildren(const SyntheticChildren &) = delete;
  const SyntheticChildren &operator=(const SyntheticChildren &) = delete;
};

class TypeFilterImpl : public SyntheticChildren {
  std::vector<std::string> m_expression_paths;

public:
  TypeFilterImpl(const SyntheticChildren::Flags &flags)
      : SyntheticChildren(flags) {}

  TypeFilterImpl(const SyntheticChildren::Flags &flags,
                 const std::initializer_list<const char *> items)
      : SyntheticChildren(flags) {
    for (auto path : items)
      AddExpressionPath(path);
  }

  void AddExpressionPath(const char *path) {
    AddExpressionPath(std::string(path));
  }

  void Clear() { m_expression_paths.clear(); }

  size_t GetCount() const { return m_expression_paths.size(); }

  const char *GetExpressionPathAtIndex(size_t i) const {
    return m_expression_paths[i].c_str();
  }

  bool SetExpressionPathAtIndex(size_t i, const char *path) {
    return SetExpressionPathAtIndex(i, std::string(path));
  }

  void AddExpressionPath(const std::string &path);

  bool SetExpressionPathAtIndex(size_t i, const std::string &path);

  bool IsScripted() override { return false; }

  std::string GetDescription() override;

  class FrontEnd : public SyntheticChildrenFrontEnd {
  public:
    FrontEnd(TypeFilterImpl *flt, ValueObject &backend)
        : SyntheticChildrenFrontEnd(backend), filter(flt) {}

    ~FrontEnd() override = default;

    size_t CalculateNumChildren() override { return filter->GetCount(); }

    lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
      if (idx >= filter->GetCount())
        return lldb::ValueObjectSP();
      return m_backend.GetSyntheticExpressionPathChild(
          filter->GetExpressionPathAtIndex(idx), true);
    }

    bool Update() override { return false; }

    bool MightHaveChildren() override { return filter->GetCount() > 0; }

    size_t GetIndexOfChildWithName(ConstString name) override;

    typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;

  private:
    TypeFilterImpl *filter;

    FrontEnd(const FrontEnd &) = delete;
    const FrontEnd &operator=(const FrontEnd &) = delete;
  };

  SyntheticChildrenFrontEnd::AutoPointer
  GetFrontEnd(ValueObject &backend) override {
    return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
  }

  typedef std::shared_ptr<TypeFilterImpl> SharedPointer;

private:
  TypeFilterImpl(const TypeFilterImpl &) = delete;
  const TypeFilterImpl &operator=(const TypeFilterImpl &) = delete;
};

class CXXSyntheticChildren : public SyntheticChildren {
public:
  typedef std::function<SyntheticChildrenFrontEnd *(CXXSyntheticChildren *,
                                                    lldb::ValueObjectSP)>
      CreateFrontEndCallback;
  CXXSyntheticChildren(const SyntheticChildren::Flags &flags,
                       const char *description, CreateFrontEndCallback callback)
      : SyntheticChildren(flags), m_create_callback(std::move(callback)),
        m_description(description ? description : "") {}

  bool IsScripted() override { return false; }

  std::string GetDescription() override;

  SyntheticChildrenFrontEnd::AutoPointer
  GetFrontEnd(ValueObject &backend) override {
    return SyntheticChildrenFrontEnd::AutoPointer(
        m_create_callback(this, backend.GetSP()));
  }

protected:
  CreateFrontEndCallback m_create_callback;
  std::string m_description;

private:
  CXXSyntheticChildren(const CXXSyntheticChildren &) = delete;
  const CXXSyntheticChildren &operator=(const CXXSyntheticChildren &) = delete;
};

class ScriptedSyntheticChildren : public SyntheticChildren {
  std::string m_python_class;
  std::string m_python_code;

public:
  ScriptedSyntheticChildren(const SyntheticChildren::Flags &flags,
                            const char *pclass, const char *pcode = nullptr)
      : SyntheticChildren(flags) {
    if (pclass)
      m_python_class = pclass;
    if (pcode)
      m_python_code = pcode;
  }

  const char *GetPythonClassName() { return m_python_class.c_str(); }

  const char *GetPythonCode() { return m_python_code.c_str(); }

  void SetPythonClassName(const char *fname) {
    m_python_class.assign(fname);
    m_python_code.clear();
  }

  void SetPythonCode(const char *script) { m_python_code.assign(script); }

  std::string GetDescription() override;

  bool IsScripted() override { return true; }

  class FrontEnd : public SyntheticChildrenFrontEnd {
  public:
    FrontEnd(std::string pclass, ValueObject &backend);

    ~FrontEnd() override;

    bool IsValid();

    size_t CalculateNumChildren() override;

    size_t CalculateNumChildren(uint32_t max) override;

    lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;

    bool Update() override;

    bool MightHaveChildren() override;

    size_t GetIndexOfChildWithName(ConstString name) override;

    lldb::ValueObjectSP GetSyntheticValue() override;

    ConstString GetSyntheticTypeName() override;

    typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;

  private:
    std::string m_python_class;
    StructuredData::ObjectSP m_wrapper_sp;
    ScriptInterpreter *m_interpreter;

    FrontEnd(const FrontEnd &) = delete;
    const FrontEnd &operator=(const FrontEnd &) = delete;
  };

  SyntheticChildrenFrontEnd::AutoPointer
  GetFrontEnd(ValueObject &backend) override {
    auto synth_ptr = SyntheticChildrenFrontEnd::AutoPointer(
        new FrontEnd(m_python_class, backend));
    if (synth_ptr && ((FrontEnd *)synth_ptr.get())->IsValid())
      return synth_ptr;
    return nullptr;
  }

private:
  ScriptedSyntheticChildren(const ScriptedSyntheticChildren &) = delete;
  const ScriptedSyntheticChildren &
  operator=(const ScriptedSyntheticChildren &) = delete;
};
} // namespace lldb_private

#endif // LLDB_DATAFORMATTERS_TYPESYNTHETIC_H
