/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#ifndef cmArchiveWrite_h
#define cmArchiveWrite_h

#include "cmStandardIncludes.h"

#if !defined(CMAKE_BUILD_WITH_CMAKE)
# error "cmArchiveWrite not allowed during bootstrap build!"
#endif

template<typename T>
class cmArchiveWriteOptional
{
public:
  cmArchiveWriteOptional() {this->Clear();}
  explicit cmArchiveWriteOptional(T val) {this->Set(val);}

  void Set(T val) {this->IsValueSet = true; this->Value=val;}
  void Clear() {this->IsValueSet = false;}
  bool IsSet() const {return this->IsValueSet;}
  T Get() const {return Value;}
private:
  T Value;
  bool IsValueSet;
};

/** \class cmArchiveWrite
 * \brief Wrapper around libarchive for writing.
 *
 */
class cmArchiveWrite
{
  typedef void (cmArchiveWrite::* safe_bool)();
  void safe_bool_true() {}
public:
  /** Compression type.  */
  enum Compress
  {
    CompressNone,
    CompressCompress,
    CompressGZip,
    CompressBZip2,
    CompressLZMA,
    CompressXZ
  };

  /** Construct with output stream to which to write archive.  */
  cmArchiveWrite(std::ostream& os, Compress c = CompressNone,
    std::string const& format = "paxr");

  ~cmArchiveWrite();

  /**
   * Add a path (file or directory) to the archive.  Directories are
   * added recursively.  The "path" must be readable on disk, either
   * full path or relative to current working directory.  The "skip"
   * value indicates how many leading bytes from the input path to
   * skip.  The remaining part of the input path is appended to the
   * "prefix" value to construct the final name in the archive.
   */
  bool Add(std::string path,
     size_t skip = 0,
     const char* prefix = 0,
     bool recursive = true);

  /** Returns true if there has been no error.  */
  operator safe_bool() const
    { return this->Okay()? &cmArchiveWrite::safe_bool_true : 0; }

  /** Returns true if there has been an error.  */
  bool operator!() const { return !this->Okay(); }

  /** Return the error string; empty if none.  */
  std::string GetError() const { return this->Error; }

  // TODO: More general callback instead of hard-coding calls to
  // std::cout.
  void SetVerbose(bool v) { this->Verbose = v; }

  void SetMTime(std::string const& t) { this->MTime = t; }

  //! Sets the permissions of the added files/folders
  void SetPermissions(mode_t permissions_)
    {
    this->Permissions.Set(permissions_);
    }

  //! Clears permissions - default is used instead
  void ClearPermissions() { this->Permissions.Clear(); }

  //! Sets the permissions mask of files/folders
  //!
  //! The permissions will be copied from the existing file
  //! or folder. The mask will then be applied to unset
  //! some of them
  void SetPermissionsMask(mode_t permissionsMask_)
    {
    this->PermissionsMask.Set(permissionsMask_);
    }

  //! Clears permissions mask - default is used instead
  void ClearPermissionsMask()
    {
    this->PermissionsMask.Clear();
    }

  //! Sets UID and GID to be used in the tar file
  void SetUIDAndGID(int uid_, int gid_)
    {
    this->Uid.Set(uid_);
    this->Gid.Set(gid_);
    }

  //! Clears UID and GID to be used in the tar file - default is used instead
  void ClearUIDAndGID()
    {
    this->Uid.Clear();
    this->Gid.Clear();
    }

  //! Sets UNAME and GNAME to be used in the tar file
  void SetUNAMEAndGNAME(const std::string& uname_, const std::string& gname_)
    {
    this->Uname = uname_;
    this->Gname = gname_;
    }

  //! Clears UNAME and GNAME to be used in the tar file
  //! default is used instead
  void ClearUNAMEAndGNAME()
    {
    this->Uname = "";
    this->Gname = "";
    }

private:
  bool Okay() const { return this->Error.empty(); }
  bool AddPath(const char* path, size_t skip, const char* prefix,
               bool recursive = true);
  bool AddFile(const char* file, size_t skip, const char* prefix);
  bool AddData(const char* file, size_t size);

  struct Callback;
  friend struct Callback;

  class Entry;

  std::ostream& Stream;
  struct archive* Archive;
  struct archive* Disk;
  bool Verbose;
  std::string Format;
  std::string Error;
  std::string MTime;

  //! UID of the user in the tar file
  cmArchiveWriteOptional<int> Uid;

  //! GUID of the user in the tar file
  cmArchiveWriteOptional<int> Gid;

  //! UNAME/GNAME of the user (does not override UID/GID)
  //!@{
  std::string Uname;
  std::string Gname;
  //!@}

  //! Permissions on files/folders
  cmArchiveWriteOptional<mode_t> Permissions;
  cmArchiveWriteOptional<mode_t> PermissionsMask;
};

#endif
