//===-- TypeSummary.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_TypeSummary_h_
#define lldb_TypeSummary_h_

#include <stdint.h>

#include <functional>
#include <memory>
#include <string>

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

#include "lldb/Core/FormatEntity.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StructuredData.h"

namespace lldb_private {
class TypeSummaryOptions {
public:
  TypeSummaryOptions();

  ~TypeSummaryOptions() = default;

  lldb::LanguageType GetLanguage() const;

  lldb::TypeSummaryCapping GetCapping() const;

  TypeSummaryOptions &SetLanguage(lldb::LanguageType);

  TypeSummaryOptions &SetCapping(lldb::TypeSummaryCapping);

private:
  lldb::LanguageType m_lang;
  lldb::TypeSummaryCapping m_capping;
};

class TypeSummaryImpl {
public:
  enum class Kind { eSummaryString, eScript, eCallback, eInternal };

  virtual ~TypeSummaryImpl() = default;

  Kind GetKind() const { return m_kind; }

  class Flags {
  public:
    Flags() : m_flags(lldb::eTypeOptionCascade) {}

    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 GetDontShowChildren() const {
      return (m_flags & lldb::eTypeOptionHideChildren) ==
             lldb::eTypeOptionHideChildren;
    }

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

    bool GetHideEmptyAggregates() const {
      return (m_flags & lldb::eTypeOptionHideEmptyAggregates) ==
             lldb::eTypeOptionHideEmptyAggregates;
    }

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

    bool GetDontShowValue() const {
      return (m_flags & lldb::eTypeOptionHideValue) ==
             lldb::eTypeOptionHideValue;
    }

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

    bool GetShowMembersOneLiner() const {
      return (m_flags & lldb::eTypeOptionShowOneLiner) ==
             lldb::eTypeOptionShowOneLiner;
    }

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

    bool GetHideItemNames() const {
      return (m_flags & lldb::eTypeOptionHideNames) ==
             lldb::eTypeOptionHideNames;
    }

    Flags &SetHideItemNames(bool value = true) {
      if (value)
        m_flags |= lldb::eTypeOptionHideNames;
      else
        m_flags &= ~lldb::eTypeOptionHideNames;
      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;
    }

    uint32_t GetValue() { return m_flags; }

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

  private:
    uint32_t m_flags;
  };

  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(); }

  virtual bool DoesPrintChildren(ValueObject *valobj) const {
    return !m_flags.GetDontShowChildren();
  }

  virtual bool DoesPrintEmptyAggregates() const {
    return !m_flags.GetHideEmptyAggregates();
  }

  virtual bool DoesPrintValue(ValueObject *valobj) const {
    return !m_flags.GetDontShowValue();
  }

  bool IsOneLiner() const { return m_flags.GetShowMembersOneLiner(); }

  virtual bool HideNames(ValueObject *valobj) const {
    return m_flags.GetHideItemNames();
  }

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

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

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

  virtual void SetDoesPrintChildren(bool value) {
    m_flags.SetDontShowChildren(!value);
  }

  virtual void SetDoesPrintValue(bool value) {
    m_flags.SetDontShowValue(!value);
  }

  void SetIsOneLiner(bool value) { m_flags.SetShowMembersOneLiner(value); }

  virtual void SetHideNames(bool value) { m_flags.SetHideItemNames(value); }

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

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

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

  // we are using a ValueObject* instead of a ValueObjectSP because we do not
  // need to hold on to this for extended periods of time and we trust the
  // ValueObject to stay around for as long as it is required for us to
  // generate its summary
  virtual bool FormatObject(ValueObject *valobj, std::string &dest,
                            const TypeSummaryOptions &options) = 0;

  virtual std::string GetDescription() = 0;

  uint32_t &GetRevision() { return m_my_revision; }

  typedef std::shared_ptr<TypeSummaryImpl> SharedPointer;

protected:
  uint32_t m_my_revision;
  Flags m_flags;

  TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags);

private:
  Kind m_kind;
  DISALLOW_COPY_AND_ASSIGN(TypeSummaryImpl);
};

// simple string-based summaries, using ${var to show data
struct StringSummaryFormat : public TypeSummaryImpl {
  std::string m_format_str;
  FormatEntity::Entry m_format;
  Status m_error;

  StringSummaryFormat(const TypeSummaryImpl::Flags &flags, const char *f);

  ~StringSummaryFormat() override = default;

  const char *GetSummaryString() const { return m_format_str.c_str(); }

  void SetSummaryString(const char *f);

  bool FormatObject(ValueObject *valobj, std::string &dest,
                    const TypeSummaryOptions &options) override;

  std::string GetDescription() override;

  static bool classof(const TypeSummaryImpl *S) {
    return S->GetKind() == Kind::eSummaryString;
  }

private:
  DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat);
};

// summaries implemented via a C++ function
struct CXXFunctionSummaryFormat : public TypeSummaryImpl {
  // we should convert these to SBValue and SBStream if we ever cross the
  // boundary towards the external world
  typedef std::function<bool(ValueObject &, Stream &,
                             const TypeSummaryOptions &)>
      Callback;

  Callback m_impl;
  std::string m_description;

  CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags &flags, Callback impl,
                           const char *description);

  ~CXXFunctionSummaryFormat() override = default;

  Callback GetBackendFunction() const { return m_impl; }

  const char *GetTextualInfo() const { return m_description.c_str(); }

  void SetBackendFunction(Callback cb_func) { m_impl = cb_func; }

  void SetTextualInfo(const char *descr) {
    if (descr)
      m_description.assign(descr);
    else
      m_description.clear();
  }

  bool FormatObject(ValueObject *valobj, std::string &dest,
                    const TypeSummaryOptions &options) override;

  std::string GetDescription() override;

  static bool classof(const TypeSummaryImpl *S) {
    return S->GetKind() == Kind::eCallback;
  }

  typedef std::shared_ptr<CXXFunctionSummaryFormat> SharedPointer;

private:
  DISALLOW_COPY_AND_ASSIGN(CXXFunctionSummaryFormat);
};

// Python-based summaries, running script code to show data
struct ScriptSummaryFormat : public TypeSummaryImpl {
  std::string m_function_name;
  std::string m_python_script;
  StructuredData::ObjectSP m_script_function_sp;

  ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags,
                      const char *function_name,
                      const char *python_script = nullptr);

  ~ScriptSummaryFormat() override = default;

  const char *GetFunctionName() const { return m_function_name.c_str(); }

  const char *GetPythonScript() const { return m_python_script.c_str(); }

  void SetFunctionName(const char *function_name) {
    if (function_name)
      m_function_name.assign(function_name);
    else
      m_function_name.clear();
    m_python_script.clear();
  }

  void SetPythonScript(const char *script) {
    if (script)
      m_python_script.assign(script);
    else
      m_python_script.clear();
  }

  bool FormatObject(ValueObject *valobj, std::string &dest,
                    const TypeSummaryOptions &options) override;

  std::string GetDescription() override;

  static bool classof(const TypeSummaryImpl *S) {
    return S->GetKind() == Kind::eScript;
  }

  typedef std::shared_ptr<ScriptSummaryFormat> SharedPointer;

private:
  DISALLOW_COPY_AND_ASSIGN(ScriptSummaryFormat);
};
} // namespace lldb_private

#endif // lldb_TypeSummary_h_
