//
// Copyright (C) 2009 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/payload_consumer/bzip_extent_writer.h"

using std::vector;

namespace chromeos_update_engine {

namespace {
const brillo::Blob::size_type kOutputBufferLength = 16 * 1024;
}

bool BzipExtentWriter::Init(FileDescriptorPtr fd,
                            const vector<Extent>& extents,
                            uint32_t block_size) {
  // Init bzip2 stream
  int rc = BZ2_bzDecompressInit(&stream_,
                                0,   // verbosity. (0 == silent)
                                0);  // 0 = faster algo, more memory

  TEST_AND_RETURN_FALSE(rc == BZ_OK);

  return next_->Init(fd, extents, block_size);
}

bool BzipExtentWriter::Write(const void* bytes, size_t count) {
  brillo::Blob output_buffer(kOutputBufferLength);

  // Copy the input data into |input_buffer_| only if |input_buffer_| already
  // contains unconsumed data. Otherwise, process the data directly from the
  // source.
  const uint8_t* input = reinterpret_cast<const uint8_t*>(bytes);
  const uint8_t* input_end = input + count;
  if (!input_buffer_.empty()) {
    input_buffer_.insert(input_buffer_.end(), input, input_end);
    input = input_buffer_.data();
    input_end = input + input_buffer_.size();
  }
  stream_.next_in = reinterpret_cast<char*>(const_cast<uint8_t*>(input));
  stream_.avail_in = input_end - input;

  for (;;) {
    stream_.next_out = reinterpret_cast<char*>(output_buffer.data());
    stream_.avail_out = output_buffer.size();

    int rc = BZ2_bzDecompress(&stream_);
    TEST_AND_RETURN_FALSE(rc == BZ_OK || rc == BZ_STREAM_END);

    if (stream_.avail_out == output_buffer.size())
      break;  // got no new bytes

    TEST_AND_RETURN_FALSE(
        next_->Write(output_buffer.data(),
                     output_buffer.size() - stream_.avail_out));

    if (rc == BZ_STREAM_END)
      CHECK_EQ(stream_.avail_in, 0u);
    if (stream_.avail_in == 0)
      break;  // no more input to process
  }

  // Store unconsumed data (if any) in |input_buffer_|.
  if (stream_.avail_in || !input_buffer_.empty()) {
    brillo::Blob new_input_buffer(input_end - stream_.avail_in, input_end);
    new_input_buffer.swap(input_buffer_);
  }

  return true;
}

bool BzipExtentWriter::EndImpl() {
  TEST_AND_RETURN_FALSE(input_buffer_.empty());
  TEST_AND_RETURN_FALSE(BZ2_bzDecompressEnd(&stream_) == BZ_OK);
  return next_->End();
}

}  // namespace chromeos_update_engine
