/*
 *  Copyright (c) 2012 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 "webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.h"

#include <assert.h>
#include <stdlib.h>  // NULL

#include <algorithm>
#include <limits>

namespace webrtc {

PartitionTreeNode::PartitionTreeNode(PartitionTreeNode* parent,
                                     const size_t* size_vector,
                                     size_t num_partitions,
                                     size_t this_size)
    : parent_(parent),
      this_size_(this_size),
      size_vector_(size_vector),
      num_partitions_(num_partitions),
      max_parent_size_(0),
      min_parent_size_(std::numeric_limits<int>::max()),
      packet_start_(false) {
  // If |this_size_| > INT_MAX, Cost() and CreateChildren() won't work properly.
  assert(this_size_ <= static_cast<size_t>(std::numeric_limits<int>::max()));
  children_[kLeftChild] = NULL;
  children_[kRightChild] = NULL;
}

PartitionTreeNode* PartitionTreeNode::CreateRootNode(const size_t* size_vector,
                                                     size_t num_partitions) {
  PartitionTreeNode* root_node =
      new PartitionTreeNode(NULL, &size_vector[1], num_partitions - 1,
                            size_vector[0]);
  root_node->set_packet_start(true);
  return root_node;
}

PartitionTreeNode::~PartitionTreeNode() {
  delete children_[kLeftChild];
  delete children_[kRightChild];
}

int PartitionTreeNode::Cost(size_t penalty) {
  int cost = 0;
  if (num_partitions_ == 0) {
    // This is a solution node.
    cost = std::max(max_parent_size_, this_size_int()) -
        std::min(min_parent_size_, this_size_int());
  } else {
    cost = std::max(max_parent_size_, this_size_int()) - min_parent_size_;
  }
  return cost + NumPackets() * penalty;
}

bool PartitionTreeNode::CreateChildren(size_t max_size) {
  assert(max_size > 0);
  bool children_created = false;
  if (num_partitions_ > 0) {
    if (this_size_ + size_vector_[0] <= max_size) {
      assert(!children_[kLeftChild]);
      children_[kLeftChild] =
          new PartitionTreeNode(this,
                                &size_vector_[1],
                                num_partitions_ - 1,
                                this_size_ + size_vector_[0]);
      children_[kLeftChild]->set_max_parent_size(max_parent_size_);
      children_[kLeftChild]->set_min_parent_size(min_parent_size_);
      // "Left" child is continuation of same packet.
      children_[kLeftChild]->set_packet_start(false);
      children_created = true;
    }
    if (this_size_ > 0) {
      assert(!children_[kRightChild]);
      children_[kRightChild] = new PartitionTreeNode(this,
                                                     &size_vector_[1],
                                                     num_partitions_ - 1,
                                                     size_vector_[0]);
      children_[kRightChild]->set_max_parent_size(
          std::max(max_parent_size_, this_size_int()));
      children_[kRightChild]->set_min_parent_size(
          std::min(min_parent_size_, this_size_int()));
      // "Right" child starts a new packet.
      children_[kRightChild]->set_packet_start(true);
      children_created = true;
    }
  }
  return children_created;
}

size_t PartitionTreeNode::NumPackets() {
  if (parent_ == NULL) {
    // Root node is a "right" child by definition.
    return 1;
  }
  if (parent_->children_[kLeftChild] == this) {
    // This is a "left" child.
    return parent_->NumPackets();
  } else {
    // This is a "right" child.
    return 1 + parent_->NumPackets();
  }
}

PartitionTreeNode* PartitionTreeNode::GetOptimalNode(size_t max_size,
                                                     size_t penalty) {
  CreateChildren(max_size);
  PartitionTreeNode* left = children_[kLeftChild];
  PartitionTreeNode* right = children_[kRightChild];
  if ((left == NULL) && (right == NULL)) {
    // This is a solution node; return it.
    return this;
  } else if (left == NULL) {
    // One child empty, return the other.
    return right->GetOptimalNode(max_size, penalty);
  } else if (right == NULL) {
    // One child empty, return the other.
    return left->GetOptimalNode(max_size, penalty);
  } else {
    PartitionTreeNode* first;
    PartitionTreeNode* second;
    if (left->Cost(penalty) <= right->Cost(penalty)) {
      first = left;
      second = right;
    } else {
      first = right;
      second = left;
    }
    first = first->GetOptimalNode(max_size, penalty);
    if (second->Cost(penalty) <= first->Cost(penalty)) {
      second = second->GetOptimalNode(max_size, penalty);
      // Compare cost estimate for "second" with actual cost for "first".
      if (second->Cost(penalty) < first->Cost(penalty)) {
        return second;
      }
    }
    return first;
  }
}

Vp8PartitionAggregator::Vp8PartitionAggregator(
    const RTPFragmentationHeader& fragmentation,
    size_t first_partition_idx, size_t last_partition_idx)
    : root_(NULL),
      num_partitions_(last_partition_idx - first_partition_idx + 1),
      size_vector_(new size_t[num_partitions_]),
      largest_partition_size_(0) {
  assert(last_partition_idx >= first_partition_idx);
  assert(last_partition_idx < fragmentation.fragmentationVectorSize);
  for (size_t i = 0; i < num_partitions_; ++i) {
    size_vector_[i] =
        fragmentation.fragmentationLength[i + first_partition_idx];
    largest_partition_size_ = std::max(largest_partition_size_,
                                       size_vector_[i]);
  }
  root_ = PartitionTreeNode::CreateRootNode(size_vector_, num_partitions_);
}

Vp8PartitionAggregator::~Vp8PartitionAggregator() {
  delete [] size_vector_;
  delete root_;
}

void Vp8PartitionAggregator::SetPriorMinMax(int min_size, int max_size) {
  assert(root_);
  assert(min_size >= 0);
  assert(max_size >= min_size);
  root_->set_min_parent_size(min_size);
  root_->set_max_parent_size(max_size);
}

Vp8PartitionAggregator::ConfigVec
Vp8PartitionAggregator::FindOptimalConfiguration(size_t max_size,
                                                 size_t penalty) {
  assert(root_);
  assert(max_size >= largest_partition_size_);
  PartitionTreeNode* opt = root_->GetOptimalNode(max_size, penalty);
  ConfigVec config_vector(num_partitions_, 0);
  PartitionTreeNode* temp_node = opt;
  size_t packet_index = opt->NumPackets();
  for (size_t i = num_partitions_; i > 0; --i) {
    assert(packet_index > 0);
    assert(temp_node != NULL);
    config_vector[i - 1] = packet_index - 1;
    if (temp_node->packet_start()) --packet_index;
    temp_node = temp_node->parent();
  }
  return config_vector;
}

void Vp8PartitionAggregator::CalcMinMax(const ConfigVec& config,
                                        int* min_size, int* max_size) const {
  if (*min_size < 0) {
    *min_size = std::numeric_limits<int>::max();
  }
  if (*max_size < 0) {
    *max_size = 0;
  }
  size_t i = 0;
  while (i < config.size()) {
    size_t this_size = 0;
    size_t j = i;
    while (j < config.size() && config[i] == config[j]) {
      this_size += size_vector_[j];
      ++j;
    }
    i = j;
    if (this_size < static_cast<size_t>(*min_size)) {
      *min_size = this_size;
    }
    if (this_size > static_cast<size_t>(*max_size)) {
      *max_size = this_size;
    }
  }
}

size_t Vp8PartitionAggregator::CalcNumberOfFragments(
    size_t large_partition_size,
    size_t max_payload_size,
    size_t penalty,
    int min_size,
    int max_size) {
  assert(large_partition_size > 0);
  assert(max_payload_size > 0);
  assert(min_size != 0);
  assert(min_size <= max_size);
  assert(max_size <= static_cast<int>(max_payload_size));
  // Divisions with rounding up.
  const size_t min_number_of_fragments =
      (large_partition_size + max_payload_size - 1) / max_payload_size;
  if (min_size < 0 || max_size < 0) {
    // No aggregates produced, so we do not have any size boundaries.
    // Simply split in as few partitions as possible.
    return min_number_of_fragments;
  }
  const size_t max_number_of_fragments =
      (large_partition_size + min_size - 1) / min_size;
  int num_fragments = -1;
  size_t best_cost = std::numeric_limits<size_t>::max();
  for (size_t n = min_number_of_fragments; n <= max_number_of_fragments; ++n) {
    // Round up so that we use the largest fragment.
    size_t fragment_size = (large_partition_size + n - 1) / n;
    size_t cost = 0;
    if (fragment_size < static_cast<size_t>(min_size)) {
      cost = min_size - fragment_size + n * penalty;
    } else if (fragment_size > static_cast<size_t>(max_size)) {
      cost = fragment_size - max_size + n * penalty;
    } else {
      cost = n * penalty;
    }
    if (fragment_size <= max_payload_size && cost < best_cost) {
      num_fragments = n;
      best_cost = cost;
    }
  }
  assert(num_fragments > 0);
  // TODO(mflodman) Assert disabled since it's falsely triggered, see issue 293.
  //assert(large_partition_size / num_fragments + 1 <= max_payload_size);
  return num_fragments;
}

}  // namespace
