//===-- StringPrinter.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_STRINGPRINTER_H
#define LLDB_DATAFORMATTERS_STRINGPRINTER_H

#include <functional>
#include <string>

#include "lldb/lldb-forward.h"

#include "lldb/Utility/DataExtractor.h"

namespace lldb_private {
namespace formatters {
class StringPrinter {
public:
  enum class StringElementType { ASCII, UTF8, UTF16, UTF32 };

  enum class GetPrintableElementType { ASCII, UTF8 };

  enum class EscapeStyle { CXX, Swift };

  class DumpToStreamOptions {
  public:
    DumpToStreamOptions() = default;

    void SetStream(Stream *s) { m_stream = s; }

    Stream *GetStream() const { return m_stream; }

    void SetPrefixToken(const std::string &p) { m_prefix_token = p; }

    void SetPrefixToken(std::nullptr_t) { m_prefix_token.clear(); }

    const char *GetPrefixToken() const { return m_prefix_token.c_str(); }

    void SetSuffixToken(const std::string &p) { m_suffix_token = p; }

    void SetSuffixToken(std::nullptr_t) { m_suffix_token.clear(); }

    const char *GetSuffixToken() const { return m_suffix_token.c_str(); }

    void SetQuote(char q) { m_quote = q; }

    char GetQuote() const { return m_quote; }

    void SetSourceSize(uint32_t s) { m_source_size = s; }

    uint32_t GetSourceSize() const { return m_source_size; }

    void SetNeedsZeroTermination(bool z) { m_needs_zero_termination = z; }

    bool GetNeedsZeroTermination() const { return m_needs_zero_termination; }

    void SetBinaryZeroIsTerminator(bool e) { m_zero_is_terminator = e; }

    bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; }

    void SetEscapeNonPrintables(bool e) { m_escape_non_printables = e; }

    bool GetEscapeNonPrintables() const { return m_escape_non_printables; }

    void SetIgnoreMaxLength(bool e) { m_ignore_max_length = e; }

    bool GetIgnoreMaxLength() const { return m_ignore_max_length; }

    void SetEscapeStyle(EscapeStyle style) { m_escape_style = style; }

    EscapeStyle GetEscapeStyle() const { return m_escape_style; }

  private:
    /// The used output stream.
    Stream *m_stream = nullptr;
    /// String that should be printed before the heading quote character.
    std::string m_prefix_token;
    /// String that should be printed after the trailing quote character.
    std::string m_suffix_token;
    /// The quote character that should surround the string.
    char m_quote = '"';
    /// The length of the memory region that should be dumped in bytes.
    uint32_t m_source_size = 0;
    bool m_needs_zero_termination = true;
    /// True iff non-printable characters should be escaped when dumping
    /// them to the stream.
    bool m_escape_non_printables = true;
    /// True iff the max-string-summary-length setting of the target should
    /// be ignored.
    bool m_ignore_max_length = false;
    /// True iff a zero bytes ('\0') should terminate the memory region that
    /// is being dumped.
    bool m_zero_is_terminator = true;
    /// The language-specific style for escaping special characters.
    EscapeStyle m_escape_style = EscapeStyle::CXX;
  };

  class ReadStringAndDumpToStreamOptions : public DumpToStreamOptions {
  public:
    ReadStringAndDumpToStreamOptions() = default;

    ReadStringAndDumpToStreamOptions(ValueObject &valobj);

    void SetLocation(uint64_t l) { m_location = l; }

    uint64_t GetLocation() const { return m_location; }

    void SetProcessSP(lldb::ProcessSP p) { m_process_sp = std::move(p); }

    lldb::ProcessSP GetProcessSP() const { return m_process_sp; }

    void SetHasSourceSize(bool e) { m_has_source_size = e; }

    bool HasSourceSize() const { return m_has_source_size; }

  private:
    uint64_t m_location = 0;
    lldb::ProcessSP m_process_sp;
    /// True iff we know the source size of the string.
    bool m_has_source_size = false;
  };

  class ReadBufferAndDumpToStreamOptions : public DumpToStreamOptions {
  public:
    ReadBufferAndDumpToStreamOptions() = default;

    ReadBufferAndDumpToStreamOptions(ValueObject &valobj);

    ReadBufferAndDumpToStreamOptions(
        const ReadStringAndDumpToStreamOptions &options);

    void SetData(DataExtractor d) { m_data = d; }

    lldb_private::DataExtractor GetData() const { return m_data; }

    void SetIsTruncated(bool t) { m_is_truncated = t; }

    bool GetIsTruncated() const { return m_is_truncated; }
  private:
    DataExtractor m_data;
    bool m_is_truncated = false;
  };

  template <StringElementType element_type>
  static bool
  ReadStringAndDumpToStream(const ReadStringAndDumpToStreamOptions &options);

  template <StringElementType element_type>
  static bool
  ReadBufferAndDumpToStream(const ReadBufferAndDumpToStreamOptions &options);
};

} // namespace formatters
} // namespace lldb_private

#endif // LLDB_DATAFORMATTERS_STRINGPRINTER_H
