// Copyright 2019 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 SMBFS_SMB_FILESYSTEM_H_
#define SMBFS_SMB_FILESYSTEM_H_

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

#include <atomic>
#include <memory>
#include <ostream>
#include <string>
#include <unordered_map>
#include <vector>

#include <base/callback.h>
#include <base/containers/mru_cache.h>
#include <base/files/file_path.h>
#include <base/macros.h>
#include <base/memory/weak_ptr.h>
#include <base/synchronization/lock.h>
#include <base/threading/thread.h>
#include <base/time/time.h>
#include <base/threading/thread_task_runner_handle.h>
#include <gtest/gtest_prod.h>

#include "smbfs/filesystem.h"
#include "smbfs/inode_map.h"
#include "smbfs/recursive_delete_operation.h"
#include "smbfs/smb_credential.h"

namespace smbfs {

class SambaInterface;

class SmbFilesystem : public Filesystem {
 public:
  // Delegate functions will always be called on the SmbFilesystem's constructor
  // thread. Any callback parameters must be invoked on the caller thread (read:
  // constructor thread).
  class Delegate {
   public:
    using RequestCredentialsCallback =
        base::OnceCallback<void(std::unique_ptr<SmbCredential> credentials)>;

    // Request username/password auth credentials for the share. Invoke
    // |callback| with the requested credentials, or with nullptr if no
    // credentials are provided (eg. if the user closes the request dialog).
    virtual void RequestCredentials(RequestCredentialsCallback callback) = 0;
  };

  struct Options {
    Options();
    ~Options();

    // Allow moves.
    Options(Options&&);
    Options& operator=(Options&&);

    std::string share_path;
    uid_t uid = 0;
    gid_t gid = 0;
    std::unique_ptr<SmbCredential> credentials;
    bool allow_ntlm = false;
    bool use_kerberos = false;
  };

  enum class ConnectError {
    kOk = 0,
    kNotFound,
    kAccessDenied,
    kSmb1Unsupported,
    kUnknownError,
  };

  SmbFilesystem(Delegate* delegate, Options options);
  ~SmbFilesystem() override;

  base::WeakPtr<SmbFilesystem> GetWeakPtr();

  // Ensures that the SMB share can be connected to. Must NOT be called after
  // the filesystem is attached to a FUSE session.
  // Virtual for testing.
  virtual ConnectError EnsureConnected();

  // Sets the resolved IP address of the share host. |ip_address| is an IPv4
  // address in network byte order, or empty. If |ip_address| is empty, any
  // existing resolved address will be reset.
  // Virtual for testing.
  virtual void SetResolvedAddress(const std::vector<uint8_t>& ip_address);

  const std::string& resolved_share_path() const {
    return resolved_share_path_;
  }

  // Filesystem overrides.
  void StatFs(std::unique_ptr<StatFsRequest> request,
              fuse_ino_t inode) override;
  void Lookup(std::unique_ptr<EntryRequest> request,
              fuse_ino_t parent_inode,
              const std::string& name) override;
  void Forget(fuse_ino_t inode, uint64_t count) override;
  void GetAttr(std::unique_ptr<AttrRequest> request, fuse_ino_t inode) override;
  void SetAttr(std::unique_ptr<AttrRequest> request,
               fuse_ino_t inode,
               base::Optional<uint64_t> file_handle,
               const struct stat& attr,
               int to_set) override;
  void Open(std::unique_ptr<OpenRequest> request,
            fuse_ino_t inode,
            int flags) override;
  void Create(std::unique_ptr<CreateRequest> request,
              fuse_ino_t parent_inode,
              const std::string& name,
              mode_t mode,
              int flags) override;
  void Read(std::unique_ptr<BufRequest> request,
            fuse_ino_t inode,
            uint64_t file_handle,
            size_t size,
            off_t offset) override;
  void Write(std::unique_ptr<WriteRequest> request,
             fuse_ino_t inode,
             uint64_t file_handle,
             const char* buf,
             size_t size,
             off_t offset) override;
  void Release(std::unique_ptr<SimpleRequest> request,
               fuse_ino_t inode,
               uint64_t file_handle) override;
  void Rename(std::unique_ptr<SimpleRequest> request,
              fuse_ino_t old_parent_inode,
              const std::string& old_name,
              fuse_ino_t new_parent_inode,
              const std::string& new_name) override;
  void Unlink(std::unique_ptr<SimpleRequest> request,
              fuse_ino_t parent_inode,
              const std::string& name) override;
  void OpenDir(std::unique_ptr<OpenRequest> request,
               fuse_ino_t inode,
               int flags) override;
  void ReadDir(std::unique_ptr<DirentryRequest> request,
               fuse_ino_t inode,
               uint64_t file_handle,
               off_t offset) override;
  void ReleaseDir(std::unique_ptr<SimpleRequest> request,
                  fuse_ino_t inode,
                  uint64_t file_handle) override;
  void MkDir(std::unique_ptr<EntryRequest> request,
             fuse_ino_t parent_inode,
             const std::string& name,
             mode_t mode) override;
  void RmDir(std::unique_ptr<SimpleRequest> request,
             fuse_ino_t parent_inode,
             const std::string& name) override;

  // mojom::SmbFs helpers.
  //
  // Recursively deletes |path| and all of its contents if it is a directory.
  // |path| is an absolute path from the root of the share (ie. it does not
  // include the smb://host portion). |callback| is called with the outcome of
  // the operation.
  void DeleteRecursively(const base::FilePath& path,
                         RecursiveDeleteOperation::CompletionCallback callback);

 protected:
  // Protected constructor for unit tests.
  SmbFilesystem(Delegate* delegate, const std::string& share_path);

  // Allow mock interface to be provided during tests.
  void SetSambaInterface(std::unique_ptr<SambaInterface> samba_interface);

 private:
  FRIEND_TEST(SmbFilesystemTest, MakeStatModeBits);
  FRIEND_TEST(SmbFilesystemTest, MaybeUpdateCredentials_NoRequest);
  FRIEND_TEST(SmbFilesystemTest, MaybeUpdateCredentials_RequestOnEPERM);
  FRIEND_TEST(SmbFilesystemTest, MaybeUpdateCredentials_RequestOnEACCES);
  FRIEND_TEST(SmbFilesystemTest, MaybeUpdateCredentials_NoDelegate);
  FRIEND_TEST(SmbFilesystemTest, MaybeUpdateCredentials_OnlyOneRequest);
  FRIEND_TEST(SmbFilesystemTest, MaybeUpdateCredentials_IgnoreEmptyResponse);

  // Cache stat information when listing directories to reduce unnecessary
  // network requests.
  struct StatCacheItem {
    struct stat inode_stat;
    base::Time expires_at;
  };

  // Filesystem implementations that execute on |samba_thread_|.
  void StatFsInternal(std::unique_ptr<StatFsRequest> request, fuse_ino_t inode);
  void LookupInternal(std::unique_ptr<EntryRequest> request,
                      fuse_ino_t parent_inode,
                      const std::string& name);
  void ForgetInternal(fuse_ino_t inode, uint64_t count);
  void GetAttrInternal(std::unique_ptr<AttrRequest> request, fuse_ino_t inode);
  void SetAttrInternal(std::unique_ptr<AttrRequest> request,
                       fuse_ino_t inode,
                       base::Optional<uint64_t> file_handle,
                       const struct stat& attr,
                       int to_set);
  int SetFileSizeInternal(const std::string& share_file_path,
                          base::Optional<uint64_t> file_handle,
                          off_t size,
                          const struct stat& current_stat,
                          struct stat* reply_stat);
  int SetUtimesInternal(const std::string& share_file_path,
                        int to_set,
                        const struct timespec& atime,
                        const struct timespec& mtime,
                        const struct stat& current_stat,
                        struct stat* reply_stat);
  void OpenInternal(std::unique_ptr<OpenRequest> request,
                    fuse_ino_t inode,
                    int flags);
  void CreateInternal(std::unique_ptr<CreateRequest> request,
                      fuse_ino_t parent_inode,
                      const std::string& name,
                      mode_t mode,
                      int flags);
  void ReadInternal(std::unique_ptr<BufRequest> request,
                    fuse_ino_t inode,
                    uint64_t file_handle,
                    size_t size,
                    off_t offset);
  void WriteInternal(std::unique_ptr<WriteRequest> request,
                     fuse_ino_t inode,
                     uint64_t file_handle,
                     const std::vector<char>& buf,
                     off_t offset);
  void ReleaseInternal(std::unique_ptr<SimpleRequest> request,
                       fuse_ino_t inode,
                       uint64_t file_handle);
  void RenameInternal(std::unique_ptr<SimpleRequest> request,
                      fuse_ino_t old_parent_inode,
                      const std::string& old_name,
                      fuse_ino_t new_parent_inode,
                      const std::string& new_name);
  void UnlinkInternal(std::unique_ptr<SimpleRequest> request,
                      fuse_ino_t parent_inode,
                      const std::string& name);
  void OpenDirInternal(std::unique_ptr<OpenRequest> request,
                       fuse_ino_t inode,
                       int flags);
  void ReadDirInternal(std::unique_ptr<DirentryRequest> request,
                       fuse_ino_t inode,
                       uint64_t file_handle,
                       off_t offset);
  void ReleaseDirInternal(std::unique_ptr<SimpleRequest> request,
                          fuse_ino_t inode,
                          uint64_t file_handle);
  void MkDirInternal(std::unique_ptr<EntryRequest> request,
                     fuse_ino_t parent_inode,
                     const std::string& name,
                     mode_t mode);
  void RmDirinternal(std::unique_ptr<SimpleRequest> request,
                     fuse_ino_t parent_inode,
                     const std::string& name);

  // mojom::SmbFs helpers that execute on |samba_thread_|.
  void DeleteRecursivelyInternal(
      const base::FilePath& path,
      RecursiveDeleteOperation::CompletionCallback callback);

  // Called on completion of the recursive delete.
  void OnDeleteRecursivelyDone(
      RecursiveDeleteOperation::CompletionCallback callback,
      mojom::DeleteRecursivelyError error);

  // Constructs a sanitised stat struct for sending as a response.
  struct stat MakeStat(ino_t inode, const struct stat& in_stat) const;

  // Clear / propagate permission bits appropriately (crbug.com/1063715).
  mode_t MakeStatModeBits(mode_t in_mode) const;

  // Constructs a share file path suitable for passing to libsmbclient from the
  // given absolute file path.
  std::string MakeShareFilePath(const base::FilePath& path) const;

  // Construct a share file path from the |inode|. |inode| must be a valid inode
  // number.
  std::string ShareFilePathFromInode(ino_t inode) const;

  // Registers an open file and returns a handle to that file. Always returns a
  // non-zero handle.
  uint64_t AddOpenFile(SMBCFILE* file);

  // Removes |handle| from the open file table.
  void RemoveOpenFile(uint64_t handle);

  // Returns the open file referred to by |handle|. Returns nullptr if |handle|
  // does not exist.
  SMBCFILE* LookupOpenFile(uint64_t handle) const;

  // Request credentials, if |error| is an auth failure, and the share has not
  // previously connected successfully.
  void MaybeUpdateCredentials(int error);

  // Request authentication credentials. Will do nothing is a request is
  // currently in progress.
  void RequestCredentialUpdate();

  // Callback handler for Delegate::RequestCredentials().
  void OnRequestCredentialsDone(std::unique_ptr<SmbCredential> credentials);

  // Cache a stat structure. |inode_stat.st_ino| is used as the key.
  void AddCachedInodeStat(const struct stat& inode_stat);

  // Remove the cached stat structure for |inode|.
  void EraseCachedInodeStat(ino_t inode);

  // Lookup the cached stat structure for |inode|. Returns true on cache hit or
  // false on a miss.
  bool GetCachedInodeStat(ino_t inode, struct stat* out_stat);

  Delegate* const delegate_ = nullptr;
  const std::string share_path_;
  const uid_t uid_ = 0;
  const gid_t gid_ = 0;
  const bool use_kerberos_ = false;
  base::Thread samba_thread_;
  InodeMap inode_map_{FUSE_ROOT_ID};

  // Origin/constructor thread task runner.
  scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_ =
      base::ThreadTaskRunnerHandle::Get();

  std::unordered_map<uint64_t, SMBCFILE*> open_files_;
  uint64_t open_files_seq_ = 1;

  mutable base::Lock lock_;
  std::string resolved_share_path_ = share_path_;

  // Interface to libsmbclient.
  std::unique_ptr<SambaInterface> samba_impl_;

  // Cache stat information during ReadDir() to speed up subsequent access.
  base::HashingMRUCache<ino_t, StatCacheItem> stat_cache_;

  // Whether a successful connection to the SMB server has been made. Used to
  // determine whether or not to request auth credentials.
  // std::atomic<> load/store by default have acquire/release memory ordering.
  std::atomic<bool> connected_{false};
  // Flag to ensure only one credential request is active at a time.
  bool requesting_credentials_ = false;

  // At most one outstanding recursive delete operation can be in flight. This
  // object must live entirely on |samba_thread_|.
  std::unique_ptr<RecursiveDeleteOperation> recursive_delete_operation_;

  base::WeakPtrFactory<SmbFilesystem> weak_factory_{this};

  DISALLOW_IMPLICIT_CONSTRUCTORS(SmbFilesystem);
};

std::ostream& operator<<(std::ostream& out, SmbFilesystem::ConnectError error);

}  // namespace smbfs

#endif  // SMBFS_SMB_FILESYSTEM_H_
