// 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 CROS_DISKS_ARCHIVE_MANAGER_H_
#define CROS_DISKS_ARCHIVE_MANAGER_H_

#include <map>
#include <string>
#include <vector>

#include <gtest/gtest_prod.h>

#include "cros-disks/mount_manager.h"

namespace cros_disks {

// A derived class of MountManager for mounting archive files as a virtual
// filesystem.
class ArchiveManager : public MountManager {
 public:
  ArchiveManager(const std::string& mount_root, Platform* platform,
                 Metrics* metrics);
  ~ArchiveManager() override;

  // Initializes the manager and registers default file extensions.
  // Returns true on success.
  bool Initialize() override;

  // Stops a session. Returns true on success.
  bool StopSession() override;

  // Returns true if mounting |source_path| is supported.
  bool CanMount(const std::string& source_path) const override;

  // Returns the type of mount sources supported by the manager.
  MountSourceType GetMountSourceType() const override {
    return MOUNT_SOURCE_ARCHIVE;
  }

  // Registers a set of default archive file extensions to the manager.
  void RegisterDefaultFileExtensions();

  // Registers an archive file extension and the corresponding AVFS handler to
  // to the manager. Subsequent registrations of the same file extension
  // overwrite an existing handler. |extension| should not include the leading
  // dot. |avfs_handler| should be in the form like '#uzip', '#ugz#utar', etc.
  void RegisterFileExtension(const std::string& extension,
                             const std::string& avfs_handler);

 protected:
  // Mounts |source_path| to |mount_path| as |source_format| with |options|.
  // |source_format| can be used to specify the archive file format of
  // |source_path|, so that |source_path| can have any file extension.
  // If |source_format| is an empty string, the archive file format is
  // determined based on the file extension of |source_path|. The underlying
  // mounter may decide to apply mount options different than |options|.
  // |applied_options| is used to return the mount options applied by the
  // mounter.
  MountErrorType DoMount(const std::string& source_path,
                         const std::string& source_format,
                         const std::vector<std::string>& options,
                         const std::string& mount_path,
                         MountOptions* applied_options) override;

  // Unmounts |path| with |options|. Returns true if |path| is unmounted
  // successfully.
  MountErrorType DoUnmount(const std::string& path,
                           const std::vector<std::string>& options) override;

  // Returns a suggested mount path for a source path.
  std::string SuggestMountPath(const std::string& source_path) const override;

 private:
  // Type definition of a cache mapping a mount path to its source virtual path
  // in the AVFS mount.
  using VirtualPathMap = std::map<std::string, std::string>;

  // Returns the extension of a file, in lower case, at the specified |path|.
  std::string GetFileExtension(const std::string& path) const;

  // Returns the corresponding path inside the AVFS mount of a given |path|
  // with the archive file |extension|, or an empty string if |extension| is
  // not supported or |path| does not have a corresponding path inside the AVFS
  // mount.
  std::string GetAVFSPath(const std::string& path,
                          const std::string& extension) const;

  // Starts AVFS daemons to initialize AVFS mounts. Returns true on success or
  // if the AVFS daemons have started.
  bool StartAVFS();

  // Stops AVFS daemons and unmounts AVFS mounts. Returns true on success or if
  // the AVFS daemons have not yet started.
  bool StopAVFS();

  // Mounts |base_path| to |avfs_path| via AVFS. Return true on success.
  bool MountAVFSPath(const std::string& base_path,
                     const std::string& avfs_path) const;

  // Adds a mapping of |mount_path| to |virtual_path| to |virtual_paths_|.
  // An existing mapping of |mount_path| is overwritten.
  void AddMountVirtualPath(const std::string& mount_path,
                           const std::string& virtual_path);

  // Removes a mapping of |mount_path| to its virtual path from
  // |virtual_paths_|. It is a no-op if no such mapping exists.
  void RemoveMountVirtualPath(const std::string& mount_path);

  // A mapping of supported archive file extensions to corresponding AVFS
  // handlers.
  std::map<std::string, std::string> extension_handlers_;

  // A cache mapping a mount path to its source virtual path in the AVFS mount.
  VirtualPathMap virtual_paths_;

  // This variable is set to true if the AVFS daemons have started.
  bool avfs_started_;

  FRIEND_TEST(ArchiveManagerTest, GetAVFSPath);
  FRIEND_TEST(ArchiveManagerTest, GetAVFSPathWithInvalidPaths);
  FRIEND_TEST(ArchiveManagerTest, GetAVFSPathWithUnsupportedExtensions);
  FRIEND_TEST(ArchiveManagerTest, GetAVFSPathWithNestedArchives);
  FRIEND_TEST(ArchiveManagerTest, GetFileExtension);
  FRIEND_TEST(ArchiveManagerTest, SuggestMountPath);
  FRIEND_TEST(ArchiveManagerTest, DoMountFailedWithUnsupportedExtension);
};

}  // namespace cros_disks

#endif  // CROS_DISKS_ARCHIVE_MANAGER_H_
