/*
 *  Copyright 2004 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 "rtc_base/transformadapter.h"

#include <string.h>

#include "rtc_base/checks.h"

namespace rtc {

///////////////////////////////////////////////////////////////////////////////

TransformAdapter::TransformAdapter(StreamInterface * stream,
                                   TransformInterface * transform,
                                   bool direction_read)
    : StreamAdapterInterface(stream), transform_(transform),
      direction_read_(direction_read), state_(ST_PROCESSING), len_(0) {
}

TransformAdapter::~TransformAdapter() {
  TransformAdapter::Close();
  delete transform_;
}

StreamResult
TransformAdapter::Read(void * buffer, size_t buffer_len,
                       size_t * read, int * error) {
  if (!direction_read_)
    return SR_EOS;

  while (state_ != ST_ERROR) {
    if (state_ == ST_COMPLETE)
      return SR_EOS;

    // Buffer more data
    if ((state_ == ST_PROCESSING) && (len_ < sizeof(buffer_))) {
      size_t subread;
      StreamResult result = StreamAdapterInterface::Read(
                              buffer_ + len_,
                              sizeof(buffer_) - len_,
                              &subread,
                              &error_);
      if (result == SR_BLOCK) {
        return SR_BLOCK;
      } else if (result == SR_ERROR) {
        state_ = ST_ERROR;
        break;
      } else if (result == SR_EOS) {
        state_ = ST_FLUSHING;
      } else {
        len_ += subread;
      }
    }

    // Process buffered data
    size_t in_len = len_;
    size_t out_len = buffer_len;
    StreamResult result = transform_->Transform(buffer_, &in_len,
                                                buffer, &out_len,
                                                (state_ == ST_FLUSHING));
    RTC_DCHECK(result != SR_BLOCK);
    if (result == SR_EOS) {
      // Note: Don't signal SR_EOS this iteration, unless out_len is zero
      state_ = ST_COMPLETE;
    } else if (result == SR_ERROR) {
      state_ = ST_ERROR;
      error_ = -1; // TODO: propagate error
      break;
    } else if ((out_len == 0) && (state_ == ST_FLUSHING)) {
      // If there is no output AND no more input, then something is wrong
      state_ = ST_ERROR;
      error_ = -1; // TODO: better error code?
      break;
    }

    len_ -= in_len;
    if (len_ > 0)
      memmove(buffer_, buffer_ + in_len, len_);

    if (out_len == 0)
      continue;

    if (read)
      *read = out_len;
    return SR_SUCCESS;
  }

  if (error)
    *error = error_;
  return SR_ERROR;
}

StreamResult
TransformAdapter::Write(const void * data, size_t data_len,
                        size_t * written, int * error) {
  if (direction_read_)
    return SR_EOS;

  size_t bytes_written = 0;
  while (state_ != ST_ERROR) {
    if (state_ == ST_COMPLETE)
      return SR_EOS;

    if (len_ < sizeof(buffer_)) {
      // Process buffered data
      size_t in_len = data_len;
      size_t out_len = sizeof(buffer_) - len_;
      StreamResult result = transform_->Transform(data, &in_len,
                                                  buffer_ + len_, &out_len,
                                                  (state_ == ST_FLUSHING));

      RTC_DCHECK(result != SR_BLOCK);
      if (result == SR_EOS) {
        // Note: Don't signal SR_EOS this iteration, unless no data written
        state_ = ST_COMPLETE;
      } else if (result == SR_ERROR) {
        RTC_NOTREACHED();  // When this happens, think about what should be done
        state_ = ST_ERROR;
        error_ = -1; // TODO: propagate error
        break;
      }

      len_ = out_len;
      bytes_written = in_len;
    }

    size_t pos = 0;
    while (pos < len_) {
      size_t subwritten;
      StreamResult result = StreamAdapterInterface::Write(buffer_ + pos,
                                                          len_ - pos,
                                                          &subwritten,
                                                          &error_);
      if (result == SR_BLOCK) {
        RTC_NOTREACHED();  // We should handle this
        return SR_BLOCK;
      } else if (result == SR_ERROR) {
        state_ = ST_ERROR;
        break;
      } else if (result == SR_EOS) {
        state_ = ST_COMPLETE;
        break;
      }

      pos += subwritten;
    }

    len_ -= pos;
    if (len_ > 0)
      memmove(buffer_, buffer_ + pos, len_);

    if (bytes_written == 0)
      continue;

    if (written)
      *written = bytes_written;
    return SR_SUCCESS;
  }

  if (error)
    *error = error_;
  return SR_ERROR;
}

void
TransformAdapter::Close() {
  if (!direction_read_ && (state_ == ST_PROCESSING)) {
    state_ = ST_FLUSHING;
    do {
      Write(0, 0, nullptr, nullptr);
    } while (state_ == ST_FLUSHING);
  }
  state_ = ST_COMPLETE;
  StreamAdapterInterface::Close();
}

bool TransformAdapter::GetAvailable(size_t* size) const {
  return false;
}

bool TransformAdapter::ReserveSize(size_t size) {
  return true;
}

bool TransformAdapter::Rewind() {
  return false;
}

} // namespace rtc
