/*
 *  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/single_process_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 {

SingleProcessEncodedImageDataInjector::SingleProcessEncodedImageDataInjector() =
    default;
SingleProcessEncodedImageDataInjector::
    ~SingleProcessEncodedImageDataInjector() = default;

EncodedImage SingleProcessEncodedImageDataInjector::InjectData(
    uint16_t id,
    bool discard,
    const EncodedImage& source) {
  RTC_CHECK(source.size() >= ExtractionInfo::kUsedBufferSize);

  ExtractionInfo info;
  info.discard = discard;
  size_t insertion_pos = source.size() - ExtractionInfo::kUsedBufferSize;
  memcpy(info.origin_data, &source.data()[insertion_pos],
         ExtractionInfo::kUsedBufferSize);
  {
    MutexLock lock(&lock_);
    // Will create new one if missed.
    ExtractionInfoVector& ev = extraction_cache_[id];
    info.sub_id = ev.next_sub_id++;
    ev.infos[info.sub_id] = info;
  }

  auto buffer = EncodedImageBuffer::Create(source.data(), source.size());
  buffer->data()[insertion_pos] = id & 0x00ff;
  buffer->data()[insertion_pos + 1] = (id & 0xff00) >> 8;
  buffer->data()[insertion_pos + 2] = info.sub_id;

  EncodedImage out = source;
  out.SetEncodedData(buffer);
  return out;
}

void SingleProcessEncodedImageDataInjector::AddParticipantInCall() {
  MutexLock crit(&lock_);
  expected_receivers_count_++;
}

EncodedImageExtractionResult SingleProcessEncodedImageDataInjector::ExtractData(
    const EncodedImage& source) {
  size_t size = source.size();
  auto buffer = EncodedImageBuffer::Create(source.data(), source.size());
  EncodedImage out = source;
  out.SetEncodedData(buffer);

  std::vector<size_t> frame_sizes;
  std::vector<size_t> frame_sl_index;
  size_t max_spatial_index = out.SpatialIndex().value_or(0);
  for (size_t i = 0; i <= max_spatial_index; ++i) {
    auto frame_size = source.SpatialLayerFrameSize(i);
    if (frame_size.value_or(0)) {
      frame_sl_index.push_back(i);
      frame_sizes.push_back(frame_size.value());
    }
  }
  if (frame_sizes.empty()) {
    frame_sizes.push_back(size);
  }

  size_t prev_frames_size = 0;
  absl::optional<uint16_t> id = absl::nullopt;
  bool discard = true;
  std::vector<ExtractionInfo> extraction_infos;
  for (size_t frame_size : frame_sizes) {
    size_t insertion_pos =
        prev_frames_size + frame_size - ExtractionInfo::kUsedBufferSize;
    // Extract frame id from first 2 bytes starting from insertion pos.
    uint16_t next_id = buffer->data()[insertion_pos] +
                       (buffer->data()[insertion_pos + 1] << 8);
    // Extract frame sub id from second 3 byte starting from insertion pos.
    uint8_t sub_id = buffer->data()[insertion_pos + 2];
    RTC_CHECK(!id || *id == next_id)
        << "Different frames encoded into single encoded image: " << *id
        << " vs " << next_id;
    id = next_id;
    ExtractionInfo info;
    {
      MutexLock lock(&lock_);
      auto ext_vector_it = extraction_cache_.find(next_id);
      RTC_CHECK(ext_vector_it != extraction_cache_.end())
          << "Unknown frame_id=" << next_id;

      auto info_it = ext_vector_it->second.infos.find(sub_id);
      RTC_CHECK(info_it != ext_vector_it->second.infos.end())
          << "Unknown sub_id=" << sub_id << " for frame_id=" << next_id;
      info_it->second.received_count++;
      info = info_it->second;
      if (info.received_count == expected_receivers_count_) {
        ext_vector_it->second.infos.erase(info_it);
      }
    }
    // We need to discard encoded image only if all concatenated encoded images
    // have to be discarded.
    discard = discard && info.discard;

    extraction_infos.push_back(info);
    prev_frames_size += frame_size;
  }
  RTC_CHECK(id);

  if (discard) {
    out.set_size(0);
    for (size_t i = 0; i <= max_spatial_index; ++i) {
      out.SetSpatialLayerFrameSize(i, 0);
    }
    return EncodedImageExtractionResult{*id, out, true};
  }

  // Make a pass from begin to end to restore origin payload and erase discarded
  // encoded images.
  size_t pos = 0;
  for (size_t frame_index = 0; frame_index < frame_sizes.size();
       ++frame_index) {
    RTC_CHECK(pos < size);
    const size_t frame_size = frame_sizes[frame_index];
    const ExtractionInfo& info = extraction_infos[frame_index];
    if (info.discard) {
      // If this encoded image is marked to be discarded - erase it's payload
      // from the buffer.
      memmove(&buffer->data()[pos], &buffer->data()[pos + frame_size],
              size - pos - frame_size);
      RTC_CHECK_LT(frame_index, frame_sl_index.size())
          << "codec doesn't support discard option or the image, that was "
             "supposed to be discarded, is lost";
      out.SetSpatialLayerFrameSize(frame_sl_index[frame_index], 0);
      size -= frame_size;
    } else {
      memcpy(
          &buffer->data()[pos + frame_size - ExtractionInfo::kUsedBufferSize],
          info.origin_data, ExtractionInfo::kUsedBufferSize);
      pos += frame_size;
    }
  }
  out.set_size(pos);

  return EncodedImageExtractionResult{*id, out, discard};
}

SingleProcessEncodedImageDataInjector::ExtractionInfoVector::
    ExtractionInfoVector() = default;
SingleProcessEncodedImageDataInjector::ExtractionInfoVector::
    ~ExtractionInfoVector() = default;

}  // namespace webrtc_pc_e2e
}  // namespace webrtc
