
/*
 *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"

#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "logging/rtc_event_log/encoder/var_int.h"
#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
#include "rtc_base/bitstream_reader.h"
#include "rtc_base/checks.h"

namespace {
absl::optional<webrtc::FieldType> ConvertFieldType(uint64_t value) {
  switch (value) {
    case static_cast<uint64_t>(webrtc::FieldType::kFixed8):
      return webrtc::FieldType::kFixed8;
    case static_cast<uint64_t>(webrtc::FieldType::kFixed32):
      return webrtc::FieldType::kFixed32;
    case static_cast<uint64_t>(webrtc::FieldType::kFixed64):
      return webrtc::FieldType::kFixed64;
    case static_cast<uint64_t>(webrtc::FieldType::kVarInt):
      return webrtc::FieldType::kVarInt;
    case static_cast<uint64_t>(webrtc::FieldType::kString):
      return webrtc::FieldType::kString;
    default:
      return absl::nullopt;
  }
}
}  // namespace

namespace webrtc {

uint64_t EventParser::ReadLittleEndian(uint8_t bytes) {
  RTC_DCHECK_LE(bytes, sizeof(uint64_t));
  RTC_DCHECK_GE(bytes, 1);

  uint64_t value = 0;

  if (bytes > pending_data_.length()) {
    SetError();
    return value;
  }

  const uint8_t* p = reinterpret_cast<const uint8_t*>(pending_data_.data());
  unsigned int shift = 0;
  uint8_t remaining = bytes;
  while (remaining > 0) {
    value += (static_cast<uint64_t>(*p) << shift);
    shift += 8;
    ++p;
    --remaining;
  }

  pending_data_ = pending_data_.substr(bytes);
  return value;
}

uint64_t EventParser::ReadVarInt() {
  uint64_t output = 0;
  bool success;
  std::tie(success, pending_data_) = DecodeVarInt(pending_data_, &output);
  if (!success) {
    SetError();
  }
  return output;
}

uint64_t EventParser::ReadOptionalValuePositions() {
  RTC_DCHECK(positions_.empty());
  size_t bits_to_read = NumEventsInBatch();
  positions_.reserve(bits_to_read);
  if (pending_data_.size() * 8 < bits_to_read) {
    SetError();
    return 0;
  }

  BitstreamReader reader(pending_data_);
  for (size_t i = 0; i < bits_to_read; i++) {
    positions_.push_back(reader.ReadBit());
  }
  if (!reader.Ok()) {
    SetError();
    return 0;
  }

  size_t num_existing_values =
      std::count(positions_.begin(), positions_.end(), 1);
  pending_data_ = pending_data_.substr((bits_to_read + 7) / 8);
  return num_existing_values;
}

uint64_t EventParser::ReadSingleValue(FieldType field_type) {
  switch (field_type) {
    case FieldType::kFixed8:
      return ReadLittleEndian(/*bytes=*/1);
    case FieldType::kFixed32:
      return ReadLittleEndian(/*bytes=*/4);
    case FieldType::kFixed64:
      return ReadLittleEndian(/*bytes=*/8);
    case FieldType::kVarInt:
      return ReadVarInt();
    case FieldType::kString:
      RTC_NOTREACHED();
      SetError();
      return 0;
  }
  RTC_NOTREACHED();
  SetError();
  return 0;
}

void EventParser::ReadDeltasAndPopulateValues(
    FixedLengthEncodingParametersV3 params,
    uint64_t num_deltas,
    uint64_t base) {
  RTC_DCHECK(values_.empty());
  values_.reserve(num_deltas + 1);
  values_.push_back(base);

  if (pending_data_.size() * 8 < num_deltas * params.delta_bit_width()) {
    SetError();
    return;
  }

  BitstreamReader reader(pending_data_);
  const uint64_t top_bit = static_cast<uint64_t>(1)
                           << (params.delta_bit_width() - 1);

  uint64_t value = base;
  for (uint64_t i = 0; i < num_deltas; ++i) {
    uint64_t delta = reader.ReadBits(params.delta_bit_width());
    RTC_DCHECK_LE(value, webrtc_event_logging::MaxUnsignedValueOfBitWidth(
                             params.value_bit_width()));
    RTC_DCHECK_LE(delta, webrtc_event_logging::MaxUnsignedValueOfBitWidth(
                             params.delta_bit_width()));
    bool negative_delta = params.signed_deltas() && ((delta & top_bit) != 0);
    if (negative_delta) {
      uint64_t delta_abs = (~delta & params.delta_mask()) + 1;
      value = (value - delta_abs) & params.value_mask();
    } else {
      value = (value + delta) & params.value_mask();
    }
    values_.push_back(value);
  }

  if (!reader.Ok()) {
    SetError();
    return;
  }

  pending_data_ =
      pending_data_.substr((num_deltas * params.delta_bit_width() + 7) / 8);
}

RtcEventLogParseStatus EventParser::Initialize(absl::string_view s,
                                               bool batched) {
  pending_data_ = s;
  num_events_ = 1;

  if (batched) {
    num_events_ = ReadVarInt();
    if (!Ok()) {
      return RtcEventLogParseStatus::Error(
          "Failed to read number of events in batch.", __FILE__, __LINE__);
    }
  }
  return RtcEventLogParseStatus::Success();
}

RtcEventLogParseStatus EventParser::ParseNumericFieldInternal(
    uint64_t value_bit_width,
    FieldType field_type) {
  RTC_DCHECK(values_.empty());
  RTC_DCHECK(positions_.empty());

  if (num_events_ == 1) {
    // Just a single value in the batch.
    uint64_t base = ReadSingleValue(field_type);
    if (!Ok()) {
      return RtcEventLogParseStatus::Error("Failed to read value", __FILE__,
                                           __LINE__);
    }
    positions_.push_back(true);
    values_.push_back(base);
  } else {
    // Delta compressed batch.
    // Read delta header.
    uint64_t header_value = ReadVarInt();
    if (!Ok())
      return RtcEventLogParseStatus::Error("Failed to read delta header",
                                           __FILE__, __LINE__);
    // NB: value_bit_width may be incorrect for the field, if this isn't the
    // field we are looking for.
    absl::optional<FixedLengthEncodingParametersV3> delta_header =
        FixedLengthEncodingParametersV3::ParseDeltaHeader(header_value,
                                                          value_bit_width);
    if (!delta_header.has_value()) {
      return RtcEventLogParseStatus::Error("Failed to parse delta header",
                                           __FILE__, __LINE__);
    }

    uint64_t num_existing_deltas = NumEventsInBatch() - 1;
    if (delta_header->values_optional()) {
      size_t num_nonempty_values = ReadOptionalValuePositions();
      if (!Ok()) {
        return RtcEventLogParseStatus::Error(
            "Failed to read positions of optional values", __FILE__, __LINE__);
      }
      if (num_nonempty_values < 1 || NumEventsInBatch() < num_nonempty_values) {
        return RtcEventLogParseStatus::Error(
            "Expected at least one non_empty value", __FILE__, __LINE__);
      }
      num_existing_deltas = num_nonempty_values - 1;
    } else {
      // All elements in the batch have values.
      positions_.assign(NumEventsInBatch(), 1u);
    }

    // Read base.
    uint64_t base = ReadSingleValue(field_type);
    if (!Ok()) {
      return RtcEventLogParseStatus::Error("Failed to read value", __FILE__,
                                           __LINE__);
    }

    if (delta_header->values_equal()) {
      // Duplicate the base value num_existing_deltas times.
      values_.assign(num_existing_deltas + 1, base);
    } else {
      // Read deltas; ceil(num_existing_deltas*delta_width/8) bits
      ReadDeltasAndPopulateValues(delta_header.value(), num_existing_deltas,
                                  base);
      if (!Ok()) {
        return RtcEventLogParseStatus::Error("Failed to decode deltas",
                                             __FILE__, __LINE__);
      }
    }
  }
  return RtcEventLogParseStatus::Success();
}

RtcEventLogParseStatus EventParser::ParseStringFieldInternal() {
  RTC_DCHECK(strings_.empty());
  if (num_events_ > 1) {
    // String encoding params reserved for future use.
    uint64_t encoding_params = ReadVarInt();
    if (!Ok()) {
      return RtcEventLogParseStatus::Error("Failed to read string encoding",
                                           __FILE__, __LINE__);
    }
    if (encoding_params != 0) {
      return RtcEventLogParseStatus::Error(
          "Unrecognized string encoding parameters", __FILE__, __LINE__);
    }
  }
  strings_.reserve(num_events_);
  for (uint64_t i = 0; i < num_events_; ++i) {
    // Just a single value in the batch.
    uint64_t size = ReadVarInt();
    if (!Ok()) {
      return RtcEventLogParseStatus::Error("Failed to read string size",
                                           __FILE__, __LINE__);
    }
    if (size > pending_data_.size()) {
      return RtcEventLogParseStatus::Error("String size exceeds remaining data",
                                           __FILE__, __LINE__);
    }
    strings_.push_back(pending_data_.substr(0, size));
    pending_data_ = pending_data_.substr(size);
  }
  return RtcEventLogParseStatus::Success();
}

RtcEventLogParseStatus EventParser::ParseField(const FieldParameters& params) {
  // Verify that the event parses fields in increasing order.
  if (params.field_id == FieldParameters::kTimestampField) {
    RTC_DCHECK_EQ(last_field_id_, FieldParameters::kTimestampField);
  } else {
    RTC_DCHECK_GT(params.field_id, last_field_id_);
  }
  last_field_id_ = params.field_id;

  // Initialization for positional fields that don't encode field ID and type.
  uint64_t field_id = params.field_id;
  FieldType field_type = params.field_type;

  // Fields are encoded in increasing field_id order.
  // Skip unknown fields with field_id < params.field_id until we either
  // find params.field_id or a field with higher id, in which case we know that
  // params.field_id doesn't exist.
  while (!pending_data_.empty()) {
    absl::string_view field_start = pending_data_;
    ClearTemporaries();

    // Read tag for non-positional fields.
    if (params.field_id != FieldParameters::kTimestampField) {
      uint64_t field_tag = ReadVarInt();
      if (!Ok())
        return RtcEventLogParseStatus::Error("Failed to read field tag",
                                             __FILE__, __LINE__);
      // Split tag into field ID and field type.
      field_id = field_tag >> 3;
      absl::optional<FieldType> conversion = ConvertFieldType(field_tag & 7u);
      if (!conversion.has_value())
        return RtcEventLogParseStatus::Error("Failed to parse field type",
                                             __FILE__, __LINE__);
      field_type = conversion.value();
    }

    if (field_id > params.field_id) {
      // We've passed all fields with ids less than or equal to what we are
      // looking for. Reset pending_data_ to first field with id higher than
      // params.field_id, since we didn't find the field we were looking for.
      pending_data_ = field_start;
      return RtcEventLogParseStatus::Success();
    }

    if (field_type == FieldType::kString) {
      auto status = ParseStringFieldInternal();
      if (!status.ok()) {
        return status;
      }
    } else {
      auto status = ParseNumericFieldInternal(params.value_width, field_type);
      if (!status.ok()) {
        return status;
      }
    }

    if (field_id == params.field_id) {
      // The field we're looking for has been found and values populated.
      return RtcEventLogParseStatus::Success();
    }
  }

  // Field not found because the event ended.
  ClearTemporaries();
  return RtcEventLogParseStatus::Success();
}

RtcEventLogParseStatusOr<rtc::ArrayView<absl::string_view>>
EventParser::ParseStringField(const FieldParameters& params,
                              bool required_field) {
  using StatusOr = RtcEventLogParseStatusOr<rtc::ArrayView<absl::string_view>>;
  RTC_DCHECK_EQ(params.field_type, FieldType::kString);
  auto status = ParseField(params);
  if (!status.ok())
    return StatusOr(status);
  rtc::ArrayView<absl::string_view> strings = GetStrings();
  if (required_field && strings.size() != NumEventsInBatch()) {
    return StatusOr::Error("Required string field not found", __FILE__,
                           __LINE__);
  }
  return StatusOr(strings);
}

RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>>
EventParser::ParseNumericField(const FieldParameters& params,
                               bool required_field) {
  using StatusOr = RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>>;
  RTC_DCHECK_NE(params.field_type, FieldType::kString);
  auto status = ParseField(params);
  if (!status.ok())
    return StatusOr(status);
  rtc::ArrayView<uint64_t> values = GetValues();
  if (required_field && values.size() != NumEventsInBatch()) {
    return StatusOr::Error("Required numerical field not found", __FILE__,
                           __LINE__);
  }
  return StatusOr(values);
}

RtcEventLogParseStatusOr<EventParser::ValueAndPostionView>
EventParser::ParseOptionalNumericField(const FieldParameters& params,
                                       bool required_field) {
  using StatusOr = RtcEventLogParseStatusOr<ValueAndPostionView>;
  RTC_DCHECK_NE(params.field_type, FieldType::kString);
  auto status = ParseField(params);
  if (!status.ok())
    return StatusOr(status);
  ValueAndPostionView view{GetValues(), GetPositions()};
  if (required_field && view.positions.size() != NumEventsInBatch()) {
    return StatusOr::Error("Required numerical field not found", __FILE__,
                           __LINE__);
  }
  return StatusOr(view);
}

}  // namespace webrtc
