// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "garnet/lib/overnet/protocol/ack_frame.h"
#include <assert.h>
#include "garnet/lib/overnet/protocol/varint.h"

namespace overnet {

AckFrame::Writer::Writer(const AckFrame* ack_frame)
    : ack_frame_(ack_frame), wire_length_(ack_frame_->WrittenLength()) {}

uint64_t AckFrame::WrittenLength() const {
  uint64_t wire_length =
      varint::WireSizeFor(ack_to_seq_) + varint::WireSizeFor(DelayAndFlags());
  for (const auto block : blocks_) {
    wire_length += varint::WireSizeFor(block.acks);
    wire_length += varint::WireSizeFor(block.nacks);
  }
  return wire_length;
}

uint8_t* AckFrame::Writer::Write(uint8_t* out) const {
  uint8_t* p = out;
  p = varint::Write(ack_frame_->ack_to_seq_, p);
  p = varint::Write(ack_frame_->DelayAndFlags(), p);
  for (const auto block : ack_frame_->blocks_) {
    p = varint::Write(block.acks, p);
    p = varint::Write(block.nacks, p);
  }
  assert(p == out + wire_length_);
  return p;
}

uint64_t AckFrame::DelayAndFlags() const {
  uint64_t delay_part =
      (ack_delay_us_ >> 63) ? 0xffff'ffff'ffff'fffe : (ack_delay_us_ << 1);
  uint64_t partial_part = partial_ ? 1 : 0;
  return delay_part | partial_part;
}

StatusOr<AckFrame> AckFrame::Parse(Slice slice) {
  const uint8_t* bytes = slice.begin();
  const uint8_t* end = slice.end();
  uint64_t ack_to_seq;
  if (!varint::Read(&bytes, end, &ack_to_seq)) {
    return StatusOr<AckFrame>(StatusCode::INVALID_ARGUMENT,
                              "Failed to parse ack_to_seq from ack frame");
  }
  if (ack_to_seq == 0) {
    return StatusOr<AckFrame>(StatusCode::INVALID_ARGUMENT,
                              "Ack frame cannot ack_to_seq 0");
  }
  uint64_t delay_and_flags;
  if (!varint::Read(&bytes, end, &delay_and_flags)) {
    return StatusOr<AckFrame>(StatusCode::INVALID_ARGUMENT,
                              "Failed to parse delay_and_flags from ack frame");
  }
  bool is_partial = (delay_and_flags & 1) != 0;
  uint64_t ack_delay_us = delay_and_flags >> 1;
  AckFrame frame(ack_to_seq, ack_delay_us);
  frame.partial_ = is_partial;
  uint64_t base = ack_to_seq;
  while (bytes != end) {
    uint64_t acks, nacks;
    if (!varint::Read(&bytes, end, &acks)) {
      return StatusOr<AckFrame>(StatusCode::INVALID_ARGUMENT,
                                "Failed to read ack count from ack frame");
    }
    if (!varint::Read(&bytes, end, &nacks)) {
      return StatusOr<AckFrame>(StatusCode::INVALID_ARGUMENT,
                                "Failed to read nack count from ack frame");
    }
    if (acks >= base) {
      return StatusOr<AckFrame>(StatusCode::INVALID_ARGUMENT,
                                "Failed to read nack (too many acks)");
    }
    if (nacks > base - acks) {
      return StatusOr<AckFrame>(StatusCode::INVALID_ARGUMENT,
                                "Failed to read nack (too many nacks)");
    }
    if (nacks == 0) {
      return StatusOr<AckFrame>(StatusCode::INVALID_ARGUMENT,
                                "Nack count cannot be zero");
    }
    base -= acks;
    base -= nacks;
    frame.blocks_.push_back(Block{acks, nacks});
    frame.last_nack_ = base + 1;
  }
  return StatusOr<AckFrame>(std::move(frame));
}

std::ostream& operator<<(std::ostream& out, const AckFrame& ack_frame) {
  out << "ACK{to:" << ack_frame.ack_to_seq()
      << ", delay:" << ack_frame.ack_delay_us()
      << "us, partial:" << (ack_frame.partial() ? "yes" : "no") << ", nack=[";
  for (auto n : ack_frame.nack_seqs()) {
    out << n << ",";
  }
  return out << "]}";
}

}  // namespace overnet
