// 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 <optional>
#include <ostream>
#include <string>
#include <unordered_map>
#include <vector>

#include <base/callback.h>
#include <base/containers/lru_cache.h>
#include <base/files/file_path.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() = delete;
  SmbFilesystem(const SmbFilesystem&) = delete;
  SmbFilesystem& operator=(const SmbFilesystem&) = delete;

  ~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,
               std::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,
                       std::optional<uint64_t> file_handle,
                       const struct stat& attr,
                       int to_set);
  int SetFileSizeInternal(const std::string& share_file_path,
                          std::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::HashingLRUCache<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};
};

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

}  // namespace smbfs

#endif  // SMBFS_SMB_FILESYSTEM_H_
