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

#include <string.h>

#include "webrtc/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
