// Copyright 2021 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "common/lsp/message-stream-splitter.h"

namespace verible {
namespace lsp {
absl::Status MessageStreamSplitter::PullFrom(const ReadFun &read_fun) {
  if (!message_processor_) {
    return absl::FailedPreconditionError(
        "MessageStreamSplitter: Message processor not yet set, needed "
        "before PullFrom() called");
  }
  return ReadInput(read_fun);
}

// Return -1 if header is incomplete (not enough data yet).
// Return -2 if header complete, but does not contain a valid
//    Content-Length header (i.e. an actual problem)
// On success, returns the offset to the body and its size in "body_size"
static constexpr int kIncompleteHeader = -1;
static constexpr int kGarbledHeader = -2;
int MessageStreamSplitter::ParseHeaderGetBodyOffset(absl::string_view data,
                                                    int *body_size) {
  static constexpr absl::string_view kEndHeaderMarker = "\r\n\r\n";
  static constexpr absl::string_view kLenientEndHeaderMarker = "\n\n";
  static constexpr absl::string_view kContentLengthHeader = "Content-Length: ";

  int header_marker_len = kEndHeaderMarker.length();
  auto end_of_header = data.find(kEndHeaderMarker);
  if (end_of_header == absl::string_view::npos && lenient_lf_separation_) {
    end_of_header = data.find(kLenientEndHeaderMarker);
    header_marker_len = kLenientEndHeaderMarker.length();
  }
  if (end_of_header == absl::string_view::npos) return kIncompleteHeader;

  // Very dirty search for header - we don't check if starts with line.
  const absl::string_view header_content(data.data(), end_of_header);
  auto found_ContentLength_header = header_content.find(kContentLengthHeader);
  if (found_ContentLength_header == absl::string_view::npos) {
    return kGarbledHeader;
  }

  size_t end_key = found_ContentLength_header + kContentLengthHeader.size();
  if (!absl::SimpleAtoi(header_content.substr(end_key), body_size)) {
    return kGarbledHeader;
  }

  return end_of_header + header_marker_len;
}

// Read from data and process all fully available messages found in data.
// Updates "data" to return the remaining unprocessed data.
// Returns ok() status encountered a corrupted header.
absl::Status MessageStreamSplitter::ProcessContainedMessages(
    absl::string_view *data) {
  while (!data->empty()) {
    int body_size = 0;
    const int body_offset = ParseHeaderGetBodyOffset(*data, &body_size);
    if (body_offset == kGarbledHeader) {
      absl::string_view limited_view(
          data->data(), std::min(data->size(), static_cast<size_t>(256)));
      return absl::InvalidArgumentError(
          absl::StrCat("No `Content-Length:` header. '", limited_view, "...'"));
    }

    const int message_size = body_offset + body_size;
    if (body_offset == kIncompleteHeader ||
        message_size > static_cast<int>(data->size())) {
      return absl::OkStatus();  // Only insufficient partial buffer available.
    }

    absl::string_view header(data->data(), body_offset);
    absl::string_view body(data->data() + body_offset, body_size);
    message_processor_(header, body);

    stats_largest_body_ = std::max(stats_largest_body_, body.size());

    *data = {data->data() + message_size, data->size() - message_size};
  }
  return absl::OkStatus();
}

// Read from "read_fun", fill internal buffer and call all available
// complete messages in it.
absl::Status MessageStreamSplitter::ReadInput(const ReadFun &read_fun) {
  size_t write_offset = 0;

  // Move all we had left from last time to the beginning of the buffer.
  // This is in the same buffer, so we need to memmove()
  if (!pending_data_.empty()) {
    memmove(read_buffer_.data(), pending_data_.data(), pending_data_.size());
    write_offset = pending_data_.size();
  }

  if (write_offset == read_buffer_.size()) {
    read_buffer_.resize(2 * read_buffer_.size());
  }

  const int free_space = read_buffer_.size() - write_offset;
  int bytes_read = read_fun(read_buffer_.data() + write_offset, free_space);
  if (bytes_read <= 0) {
    // Got EOF.
    // If we still have data pending, regard this as data loss situation, as
    // we were never able to fully read the last message and send to process.
    // Otherwise, report 'Unavailable' to indicate EOF (meh, this should
    // be a better message).
    if (!pending_data_.empty()) {
      return absl::DataLossError(
          absl::StrCat("Got EOF, but still have incomplete message with ",
                       pending_data_.size(), " bytes read so far."));
    }
    return absl::UnavailableError(absl::StrCat("read() returned ", bytes_read));
  }
  stats_total_bytes_read_ += bytes_read;

  absl::string_view data(read_buffer_.data(), write_offset + bytes_read);
  if (auto status = ProcessContainedMessages(&data); !status.ok()) {
    return status;
  }

  pending_data_ = data;  // Remember for next round.

  return absl::OkStatus();
}
}  // namespace lsp
}  // namespace verible
