// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#ifndef PROTOBUF_COMPILER_HBP_OUTPUT_H_
#define PROTOBUF_COMPILER_HBP_OUTPUT_H_

#include <vector>

#include "absl/log/absl_log.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/substitute.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/io/zero_copy_stream.h"

namespace google::protobuf::hpb_generator {

class Output {
 public:
  Output(google::protobuf::io::ZeroCopyOutputStream* stream) : stream_(stream) {}
  ~Output() { stream_->BackUp((int)buffer_size_); }

  template <class... Arg>
  void operator()(absl::string_view format, const Arg&... arg) {
    Write(absl::Substitute(format, arg...));
  }

  // Indentation size in characters.
  static constexpr size_t kIndentationSize = 2;

  void Indent() { Indent(kIndentationSize); }
  void Indent(size_t size) { indent_ += size; }

  void Outdent() { Outdent(kIndentationSize); }
  void Outdent(size_t size) {
    if (indent_ < size) {
      ABSL_LOG(FATAL) << "mismatched Output indent/unindent calls";
    }
    indent_ -= size;
  }

 private:
  void Write(absl::string_view data) {
    std::string stripped;
    if (absl::StartsWith(data, "\n ")) {
      size_t indent = data.substr(1).find_first_not_of(' ');
      if (indent > indent_) {
        indent -= indent_;
      }
      if (indent != absl::string_view::npos) {
        // Remove indentation from all lines.
        auto line_prefix = data.substr(0, indent + 1);
        // The final line has an extra newline and is indented two less, eg.
        //    R"cc(
        //      UPB_INLINE $0 $1_$2(const $1 *msg) {
        //        return $1_has_$2(msg) ? *UPB_PTR_AT(msg, $3, $0) : $4;
        //      }
        //    )cc",
        std::string last_line_prefix = std::string(line_prefix);
        last_line_prefix.resize(last_line_prefix.size() - 2);
        data.remove_prefix(line_prefix.size());
        stripped = absl::StrReplaceAll(
            data, {{line_prefix, "\n"}, {last_line_prefix, "\n"}});
        data = stripped;
      }
    } else {
      WriteIndent();
    }
    WriteRaw(data);
  }

  void WriteRaw(absl::string_view data) {
    while (!data.empty()) {
      RefreshOutput();
      size_t to_write = std::min(data.size(), buffer_size_);
      memcpy(output_buffer_, data.data(), to_write);
      data.remove_prefix(to_write);
      output_buffer_ += to_write;
      buffer_size_ -= to_write;
    }
  }

  void WriteIndent() {
    if (indent_ == 0) {
      return;
    }
    size_t size = indent_;
    while (size > buffer_size_) {
      if (buffer_size_ > 0) {
        memset(output_buffer_, ' ', buffer_size_);
      }
      size -= buffer_size_;
      buffer_size_ = 0;
      RefreshOutput();
    }
    memset(output_buffer_, ' ', size);
    output_buffer_ += size;
    buffer_size_ -= size;
  }

  void RefreshOutput() {
    while (buffer_size_ == 0) {
      void* void_buffer;
      int size;
      if (!stream_->Next(&void_buffer, &size)) {
        fprintf(stderr, "upb_generator: Failed to write to to output\n");
        abort();
      }
      output_buffer_ = static_cast<char*>(void_buffer);
      buffer_size_ = size;
    }
  }

  google::protobuf::io::ZeroCopyOutputStream* stream_;
  char* output_buffer_ = nullptr;
  size_t buffer_size_ = 0;
  // Current indentation size in characters.
  size_t indent_ = 0;
  friend class OutputIndenter;
};

class OutputIndenter {
 public:
  OutputIndenter(Output& output)
      : OutputIndenter(output, Output::kIndentationSize) {}
  OutputIndenter(Output& output, size_t indent_size)
      : indent_size_(indent_size), output_(output) {
    output.Indent(indent_size);
  }
  ~OutputIndenter() { output_.Outdent(indent_size_); }

 private:
  size_t indent_size_;
  Output& output_;
};

std::string StripExtension(absl::string_view fname);
std::string ToCIdent(absl::string_view str);
std::string ToPreproc(absl::string_view str);
void EmitFileWarning(const google::protobuf::FileDescriptor* file, Output& output);
std::string MessageName(const google::protobuf::Descriptor* descriptor);
std::string FileLayoutName(const google::protobuf::FileDescriptor* file);
std::string CHeaderFilename(const google::protobuf::FileDescriptor* file);
std::string CSourceFilename(const google::protobuf::FileDescriptor* file);

}  // namespace protobuf
}  // namespace google::hpb_generator

#endif  // PROTOBUF_COMPILER_HBP_OUTPUT_H_
