// Copyright (c) 2012 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_FILESYSTEM_COPIER_ACTION_H__
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__

#include <sys/stat.h>
#include <sys/types.h>

#include <string>
#include <vector>

#include <gio/gio.h>
#include <glib.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "update_engine/action.h"
#include "update_engine/install_plan.h"
#include "update_engine/omaha_hash_calculator.h"

// This action will only do real work if it's a delta update. It will
// copy the root partition to install partition, and then terminate.

namespace chromeos_update_engine {

class SystemState;

class FilesystemCopierAction : public InstallPlanAction {
 public:
  FilesystemCopierAction(SystemState* system_state,
                         bool copying_kernel_install_path,
                         bool verify_hash);

  void PerformAction();
  void TerminateProcessing();

  // Used for testing. Return true if Cleanup() has not yet been called due
  // to a callback upon the completion or cancellation of the copier action.
  // A test should wait until IsCleanupPending() returns false before
  // terminating the glib main loop.
  bool IsCleanupPending() const;

  // Used for testing, so we can copy from somewhere other than root
  void set_copy_source(const std::string& path) { copy_source_ = path; }

  // Debugging/logging
  static std::string StaticType() { return "FilesystemCopierAction"; }
  std::string Type() const { return StaticType(); }

 private:
  friend class FilesystemCopierActionTest;
  FRIEND_TEST(FilesystemCopierActionTest, RunAsRootDetermineFilesystemSizeTest);

  // Ping-pong buffers generally cycle through the following states:
  // Empty->Reading->Full->Writing->Empty. In hash verification mode the state
  // is never set to Writing.
  enum BufferState {
    kBufferStateEmpty,
    kBufferStateReading,
    kBufferStateFull,
    kBufferStateWriting
  };

  // Callbacks from glib when the read/write operation is done.
  void AsyncReadReadyCallback(GObject *source_object, GAsyncResult *res);
  static void StaticAsyncReadReadyCallback(GObject *source_object,
                                           GAsyncResult *res,
                                           gpointer user_data);

  void AsyncWriteReadyCallback(GObject *source_object, GAsyncResult *res);
  static void StaticAsyncWriteReadyCallback(GObject *source_object,
                                            GAsyncResult *res,
                                            gpointer user_data);

  // Based on the state of the ping-pong buffers spawns appropriate read/write
  // actions asynchronously.
  void SpawnAsyncActions();

  // Cleans up all the variables we use for async operations and tells the
  // ActionProcessor we're done w/ |code| as passed in. |cancelled_| should be
  // true if TerminateProcessing() was called.
  void Cleanup(ErrorCode code);

  // Determine, if possible, the source file system size to avoid copying the
  // whole partition. Currently this supports only the root file system assuming
  // it's ext3-compatible.
  void DetermineFilesystemSize(int fd);

  // If true, this action is copying to the kernel_install_path from
  // the install plan, otherwise it's copying just to the install_path.
  const bool copying_kernel_install_path_;

  // If true, this action is running in applied update hash verification mode --
  // it computes a hash for the target install path and compares it against the
  // expected value.
  const bool verify_hash_;

  // The path to copy from. If empty (the default), the source is from the
  // passed in InstallPlan.
  std::string copy_source_;

  // If non-NULL, these are GUnixInputStream objects for the opened
  // source/destination partitions.
  GInputStream* src_stream_;
  GOutputStream* dst_stream_;

  // Ping-pong buffers for storing data we read/write. Only one buffer is being
  // read at a time and only one buffer is being written at a time.
  std::vector<char> buffer_[2];

  // The state of each buffer.
  BufferState buffer_state_[2];

  // Number of valid elements in |buffer_| if its state is kBufferStateFull.
  std::vector<char>::size_type buffer_valid_size_[2];

  // The cancellable objects for the in-flight async calls.
  GCancellable* canceller_[2];

  bool read_done_;  // true if reached EOF on the input stream.
  bool failed_;  // true if the action has failed.
  bool cancelled_;  // true if the action has been cancelled.

  // The install plan we're passed in via the input pipe.
  InstallPlan install_plan_;

  // Calculates the hash of the copied data.
  OmahaHashCalculator hasher_;

  // Copies and hashes this many bytes from the head of the input stream. This
  // field is initialized when the action is started and decremented as more
  // bytes get copied.
  int64_t filesystem_size_;

  // The global context for update_engine.
  SystemState* system_state_;

  DISALLOW_COPY_AND_ASSIGN(FilesystemCopierAction);
};

}  // namespace chromeos_update_engine

#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__
