// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_EXTENT_WRITER_H__
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_EXTENT_WRITER_H__

#include <vector>
#include "base/logging.h"
#include "update_engine/update_metadata.pb.h"
#include "update_engine/utils.h"

// ExtentWriter is an abstract class which synchronously writes to a given
// file descriptor at the extents given.

namespace chromeos_update_engine {

class ExtentWriter {
 public:
  ExtentWriter() : end_called_(false) {}
  virtual ~ExtentWriter() {
    LOG_IF(ERROR, !end_called_) << "End() not called on ExtentWriter.";
  }

  // Returns true on success.
  virtual bool Init(int fd,
                    const std::vector<Extent>& extents,
                    uint32_t block_size) = 0;

  // Returns true on success.
  virtual bool Write(const void* bytes, size_t count) = 0;

  // Should be called when all writing is complete. Returns true on success.
  // The fd is not closed. Caller is responsible for closing it.
  bool End() {
    end_called_ = true;
    return EndImpl();
  }
  virtual bool EndImpl() = 0;
 private:
  bool end_called_;
};

// DirectExtentWriter is probably the simplest ExtentWriter implementation.
// It writes the data directly into the extents.

class DirectExtentWriter : public ExtentWriter {
 public:
  DirectExtentWriter()
      : fd_(-1),
        block_size_(0),
        extent_bytes_written_(0),
        next_extent_index_(0) {}
  ~DirectExtentWriter() {}

  bool Init(int fd, const std::vector<Extent>& extents, uint32_t block_size) {
    fd_ = fd;
    block_size_ = block_size;
    extents_ = extents;
    return true;
  }
  bool Write(const void* bytes, size_t count);
  bool EndImpl() {
    return true;
  }

 private:
  int fd_;
  
  size_t block_size_;
  // Bytes written into next_extent_index_ thus far
  uint64_t extent_bytes_written_;
  std::vector<Extent> extents_;
  // The next call to write should correspond to extents_[next_extent_index_]
  std::vector<Extent>::size_type next_extent_index_;
};

// Takes an underlying ExtentWriter to which all operations are delegated.
// When End() is called, ZeroPadExtentWriter ensures that the total number
// of bytes written is a multiple of block_size_. If not, it writes zeros
// to pad as needed.

class ZeroPadExtentWriter : public ExtentWriter {
 public:
  ZeroPadExtentWriter(ExtentWriter* underlying_extent_writer)
      : underlying_extent_writer_(underlying_extent_writer),
        block_size_(0),
        bytes_written_mod_block_size_(0) {}
  ~ZeroPadExtentWriter() {}

  bool Init(int fd, const std::vector<Extent>& extents, uint32_t block_size) {
    block_size_ = block_size;
    return underlying_extent_writer_->Init(fd, extents, block_size);
  }
  bool Write(const void* bytes, size_t count) {
    if (underlying_extent_writer_->Write(bytes, count)) {
      bytes_written_mod_block_size_ += count;
      bytes_written_mod_block_size_ %= block_size_;
      return true;
    }
    return false;
  }
  bool EndImpl() {
    if (bytes_written_mod_block_size_) {
      const size_t write_size = block_size_ - bytes_written_mod_block_size_;
      std::vector<char> zeros(write_size, 0);
      TEST_AND_RETURN_FALSE(underlying_extent_writer_->Write(&zeros[0],
                                                             write_size));
    }
    return underlying_extent_writer_->End();
  }

 private:
  ExtentWriter* underlying_extent_writer_;  // The underlying ExtentWriter.
  size_t block_size_;
  size_t bytes_written_mod_block_size_;
};

}  // namespace chromeos_update_engine

#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_EXTENT_WRITER_H__
