// Copyright (c) 2010 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 FilesystemCopierAction;

template<>
class ActionTraits<FilesystemCopierAction> {
 public:
  // Takes the install plan as input
  typedef InstallPlan InputObjectType;
  // Passes the install plan as output
  typedef InstallPlan OutputObjectType;
};

class FilesystemCopierAction : public Action<FilesystemCopierAction> {
 public:
  FilesystemCopierAction(bool copying_kernel_install_path,
                         bool verify_hash);

  typedef ActionTraits<FilesystemCopierAction>::InputObjectType
  InputObjectType;
  typedef ActionTraits<FilesystemCopierAction>::OutputObjectType
  OutputObjectType;
  void PerformAction();
  void TerminateProcessing();

  // 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(ActionExitCode 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_;

  DISALLOW_COPY_AND_ASSIGN(FilesystemCopierAction);
};

}  // namespace chromeos_update_engine

#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_COPIER_ACTION_H__
