/*
 *  Copyright (c) 2019 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 "test/pc/e2e/analyzer/video/default_encoded_image_data_injector.h"

#include <algorithm>
#include <cstddef>

#include "absl/memory/memory.h"
#include "api/video/encoded_image.h"
#include "rtc_base/checks.h"

namespace webrtc {
namespace webrtc_pc_e2e {
namespace {

// The amount on which encoded image buffer will be expanded to inject frame id.
// This is 2 bytes for uint16_t frame id itself and 4 bytes for original length
// of the buffer.
constexpr int kEncodedImageBufferExpansion = 6;

struct ExtractionInfo {
  size_t length;
  bool discard;
};

}  // namespace

DefaultEncodedImageDataInjector::DefaultEncodedImageDataInjector() = default;
DefaultEncodedImageDataInjector::~DefaultEncodedImageDataInjector() = default;

EncodedImage DefaultEncodedImageDataInjector::InjectData(
    uint16_t id,
    bool discard,
    const EncodedImage& source,
    int /*coding_entity_id*/) {
  EncodedImage out = source;
  out.Allocate(source.size() + kEncodedImageBufferExpansion);
  out.set_size(source.size() + kEncodedImageBufferExpansion);
  memcpy(out.data(), source.data(), source.size());
  size_t insertion_pos = source.size();
  out.data()[insertion_pos] = id & 0x00ff;
  out.data()[insertion_pos + 1] = (id & 0xff00) >> 8;
  out.data()[insertion_pos + 2] = source.size() & 0x000000ff;
  out.data()[insertion_pos + 3] = (source.size() & 0x0000ff00) >> 8;
  out.data()[insertion_pos + 4] = (source.size() & 0x00ff0000) >> 16;
  out.data()[insertion_pos + 5] = (source.size() & 0xff000000) >> 24;

  // We will store discard flag in the high bit of high byte of the size.
  RTC_CHECK_LT(source.size(), 1U << 31) << "High bit is already in use";
  out.data()[insertion_pos + 5] =
      out.data()[insertion_pos + 5] | ((discard ? 1 : 0) << 7);
  return out;
}

EncodedImageExtractionResult DefaultEncodedImageDataInjector::ExtractData(
    const EncodedImage& source,
    int /*coding_entity_id*/) {
  EncodedImage out = source;
  out.Allocate(source.size());

  size_t source_pos = source.size() - 1;
  absl::optional<uint16_t> id = absl::nullopt;
  bool discard = true;
  std::vector<ExtractionInfo> extraction_infos;
  // First make a reverse pass through whole buffer to populate frame id,
  // discard flags and concatenated encoded images length.
  while (true) {
    size_t insertion_pos = source_pos - kEncodedImageBufferExpansion + 1;
    RTC_CHECK_GE(insertion_pos, 0);
    RTC_CHECK_LE(insertion_pos + kEncodedImageBufferExpansion, source.size());
    uint16_t next_id =
        source.data()[insertion_pos] + (source.data()[insertion_pos + 1] << 8);
    RTC_CHECK(!id || id.value() == next_id)
        << "Different frames encoded into single encoded image: " << id.value()
        << " vs " << next_id;
    id = next_id;
    uint32_t length = source.data()[insertion_pos + 2] +
                      (source.data()[insertion_pos + 3] << 8) +
                      (source.data()[insertion_pos + 4] << 16) +
                      ((source.data()[insertion_pos + 5] << 24) & 0b01111111);
    bool current_discard = (source.data()[insertion_pos + 5] & 0b10000000) != 0;
    extraction_infos.push_back({length, current_discard});
    // Extraction result is discarded only if all encoded partitions are
    // discarded.
    discard = discard && current_discard;
    if (source_pos < length + kEncodedImageBufferExpansion) {
      break;
    }
    source_pos -= length + kEncodedImageBufferExpansion;
  }
  RTC_CHECK(id);
  std::reverse(extraction_infos.begin(), extraction_infos.end());
  if (discard) {
    out.set_size(0);
    return EncodedImageExtractionResult{*id, out, true};
  }

  // Now basing on populated data make a forward pass to copy required pieces
  // of data to the output buffer.
  source_pos = 0;
  size_t out_pos = 0;
  auto extraction_infos_it = extraction_infos.begin();
  while (source_pos < source.size()) {
    const ExtractionInfo& info = *extraction_infos_it;
    RTC_CHECK_LE(source_pos + kEncodedImageBufferExpansion + info.length,
                 source.size());
    if (!info.discard) {
      // Copy next encoded image payload from concatenated buffer only if it is
      // not discarded.
      memcpy(&out.data()[out_pos], &source.data()[source_pos], info.length);
      out_pos += info.length;
    }
    source_pos += info.length + kEncodedImageBufferExpansion;
    ++extraction_infos_it;
  }
  out.set_size(out_pos);

  return EncodedImageExtractionResult{id.value(), out, discard};
}

}  // namespace webrtc_pc_e2e
}  // namespace webrtc
