// Copyright 2014 The Chromium 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 "cobalt/media/formats/mp4/box_reader.h"

#include <stddef.h>
#include <string.h>

#include <algorithm>
#include <set>
#include <utility>

#include "base/memory/scoped_ptr.h"
#include "cobalt/media/formats/mp4/box_definitions.h"

namespace media {
namespace mp4 {

Box::~Box() {}

bool BufferReader::Read1(uint8_t* v) {
  RCHECK(HasBytes(1));
  *v = buf_[pos_++];
  return true;
}

// Internal implementation of multi-byte reads
template <typename T>
bool BufferReader::Read(T* v) {
  RCHECK(HasBytes(sizeof(T)));

  T tmp = 0;
  for (size_t i = 0; i < sizeof(T); i++) {
    tmp <<= 8;
    tmp += buf_[pos_++];
  }
  *v = tmp;
  return true;
}

bool BufferReader::Read2(uint16_t* v) { return Read(v); }
bool BufferReader::Read2s(int16_t* v) { return Read(v); }
bool BufferReader::Read4(uint32_t* v) { return Read(v); }
bool BufferReader::Read4s(int32_t* v) { return Read(v); }
bool BufferReader::Read8(uint64_t* v) { return Read(v); }
bool BufferReader::Read8s(int64_t* v) { return Read(v); }

bool BufferReader::ReadFourCC(FourCC* v) {
  return Read4(reinterpret_cast<uint32_t*>(v));
}

bool BufferReader::ReadVec(std::vector<uint8_t>* vec, uint64_t count) {
  RCHECK(HasBytes(count));
  vec->clear();
  vec->insert(vec->end(), buf_ + pos_, buf_ + pos_ + count);
  pos_ += count;
  return true;
}

bool BufferReader::SkipBytes(uint64_t bytes) {
  RCHECK(HasBytes(bytes));
  pos_ += bytes;
  return true;
}

bool BufferReader::Read4Into8(uint64_t* v) {
  uint32_t tmp;
  RCHECK(Read4(&tmp));
  *v = tmp;
  return true;
}

bool BufferReader::Read4sInto8s(int64_t* v) {
  // Beware of the need for sign extension.
  int32_t tmp;
  RCHECK(Read4s(&tmp));
  *v = tmp;
  return true;
}

BoxReader::BoxReader(const uint8_t* buf, const int size,
                     const scoped_refptr<MediaLog>& media_log, bool is_EOS)
    : BufferReader(buf, size),
      media_log_(media_log),
      type_(FOURCC_NULL),
      version_(0),
      flags_(0),
      scanned_(false),
      is_EOS_(is_EOS) {}

BoxReader::~BoxReader() {
  if (scanned_ && !children_.empty()) {
    for (ChildMap::iterator itr = children_.begin(); itr != children_.end();
         ++itr) {
      DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first);
    }
  }
}

// static
BoxReader* BoxReader::ReadTopLevelBox(const uint8_t* buf, const int buf_size,
                                      const scoped_refptr<MediaLog>& media_log,
                                      bool* err) {
  scoped_ptr<BoxReader> reader(new BoxReader(buf, buf_size, media_log, false));
  if (!reader->ReadHeader(err)) return NULL;

  if (!IsValidTopLevelBox(reader->type(), media_log)) {
    *err = true;
    return NULL;
  }

  if (reader->size() <= static_cast<uint64_t>(buf_size))
    return reader.release();

  return NULL;
}

// static
bool BoxReader::StartTopLevelBox(const uint8_t* buf, const int buf_size,
                                 const scoped_refptr<MediaLog>& media_log,
                                 FourCC* type, int* box_size, bool* err) {
  BoxReader reader(buf, buf_size, media_log, false);
  if (!reader.ReadHeader(err)) return false;
  if (!IsValidTopLevelBox(reader.type(), media_log)) {
    *err = true;
    return false;
  }
  *type = reader.type();
  *box_size = reader.size();
  return true;
}

// static
BoxReader* BoxReader::ReadConcatentatedBoxes(const uint8_t* buf,
                                             const int buf_size) {
  return new BoxReader(buf, buf_size, new MediaLog(), true);
}

// static
bool BoxReader::IsValidTopLevelBox(const FourCC& type,
                                   const scoped_refptr<MediaLog>& media_log) {
  switch (type) {
    case FOURCC_FTYP:
    case FOURCC_PDIN:
    case FOURCC_BLOC:
    case FOURCC_MOOV:
    case FOURCC_MOOF:
    case FOURCC_MFRA:
    case FOURCC_MDAT:
    case FOURCC_FREE:
    case FOURCC_SKIP:
    case FOURCC_META:
    case FOURCC_MECO:
    case FOURCC_STYP:
    case FOURCC_SIDX:
    case FOURCC_SSIX:
    case FOURCC_PRFT:
    case FOURCC_UUID:
    case FOURCC_EMSG:
      return true;
    default:
      // Hex is used to show nonprintable characters and aid in debugging
      MEDIA_LOG(DEBUG, media_log) << "Unrecognized top-level box type "
                                  << FourCCToString(type);
      return false;
  }
}

bool BoxReader::ScanChildren() {
  DCHECK(!scanned_);
  scanned_ = true;

  bool err = false;
  while (pos_ < size_) {
    BoxReader child(&buf_[pos_], size_ - pos_, media_log_, is_EOS_);
    if (!child.ReadHeader(&err)) break;

    children_.insert(std::pair<FourCC, BoxReader>(child.type(), child));
    pos_ += child.size();
  }

  DCHECK(!err);
  return !err && pos_ == size_;
}

bool BoxReader::HasChild(Box* child) {
  DCHECK(scanned_);
  DCHECK(child);
  return children_.count(child->BoxType()) > 0;
}

bool BoxReader::ReadChild(Box* child) {
  DCHECK(scanned_);
  FourCC child_type = child->BoxType();

  ChildMap::iterator itr = children_.find(child_type);
  RCHECK(itr != children_.end());
  DVLOG(2) << "Found a " << FourCCToString(child_type) << " box.";
  RCHECK(child->Parse(&itr->second));
  children_.erase(itr);
  return true;
}

bool BoxReader::MaybeReadChild(Box* child) {
  if (!children_.count(child->BoxType())) return true;
  return ReadChild(child);
}

bool BoxReader::ReadFullBoxHeader() {
  uint32_t vflags;
  RCHECK(Read4(&vflags));
  version_ = vflags >> 24;
  flags_ = vflags & 0xffffff;
  return true;
}

bool BoxReader::ReadHeader(bool* err) {
  uint64_t size = 0;
  *err = false;

  if (!HasBytes(8)) {
    // If EOS is known, then this is an error. If not, additional data may be
    // appended later, so this is a soft error.
    *err = is_EOS_;
    return false;
  }
  CHECK(Read4Into8(&size) && ReadFourCC(&type_));

  if (size == 0) {
    if (is_EOS_) {
      // All the data bytes are expected to be provided.
      size = size_;
    } else {
      MEDIA_LOG(DEBUG, media_log_)
          << "ISO BMFF boxes that run to EOS are not supported";
      *err = true;
      return false;
    }
  } else if (size == 1) {
    if (!HasBytes(8)) {
      // If EOS is known, then this is an error. If not, it's a soft error.
      *err = is_EOS_;
      return false;
    }
    CHECK(Read8(&size));
  }

  // Implementation-specific: support for boxes larger than 2^31 has been
  // removed.
  if (size < static_cast<uint64_t>(pos_) ||
      size > static_cast<uint64_t>(std::numeric_limits<int32_t>::max())) {
    *err = true;
    return false;
  }

  // Make sure the buffer contains at least the expected number of bytes.
  // Since the data may be appended in pieces, this can only be checked if EOS.
  if (is_EOS_ && size > size_) {
    *err = true;
    return false;
  }

  // Note that the pos_ head has advanced to the byte immediately after the
  // header, which is where we want it.
  size_ = size;
  return true;
}

}  // namespace mp4
}  // namespace media
