// Copyright 2015 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 LIBBRILLO_BRILLO_STREAMS_FILE_STREAM_H_
#define LIBBRILLO_BRILLO_STREAMS_FILE_STREAM_H_

#include <memory>

#include <base/files/file_path.h>
#include <base/macros.h>
#include <brillo/brillo_export.h>
#include <brillo/streams/stream.h>

namespace brillo {

// FileStream class provides the implementation of brillo::Stream for files
// and file-descriptor-based streams, such as pipes and sockets.
// The FileStream class cannot be instantiated by clients directly. However
// they should use the static factory methods such as:
//  - FileStream::Open(): to open a file by name.
//  - FileStream::CreateTemporary(): to create a temporary file stream.
//  - FileStream::FromFileDescriptor(): to create a stream using an existing
//    file descriptor.
class BRILLO_EXPORT FileStream : public Stream {
 public:
  // See comments for FileStream::Open() for detailed description of this enum.
  enum class Disposition {
    OPEN_EXISTING,    // Open existing file only. Fail if doesn't exist.
    CREATE_ALWAYS,    // Create empty file, possibly overwriting existing file.
    CREATE_NEW_ONLY,  // Create new file if doesn't exist already.
    TRUNCATE_EXISTING,  // Open/truncate existing file. Fail if doesn't exist.
  };

  // Simple interface to wrap native library calls so that they can be mocked
  // out for testing.
  struct FileDescriptorInterface {
    using DataCallback = base::Callback<void(Stream::AccessMode)>;

    virtual ~FileDescriptorInterface() = default;

    virtual bool IsOpen() const = 0;
    virtual ssize_t Read(void* buf, size_t nbyte) = 0;
    virtual ssize_t Write(const void* buf, size_t nbyte) = 0;
    virtual off64_t Seek(off64_t offset, int whence) = 0;
    virtual mode_t GetFileMode() const = 0;
    virtual uint64_t GetSize() const = 0;
    virtual int Truncate(off64_t length) const = 0;
    virtual int Close() = 0;
    virtual bool WaitForData(AccessMode mode,
                             const DataCallback& data_callback,
                             ErrorPtr* error) = 0;
    virtual int WaitForDataBlocking(AccessMode in_mode,
                                    base::TimeDelta timeout,
                                    AccessMode* out_mode) = 0;
    virtual void CancelPendingAsyncOperations() = 0;
  };

  // == Construction ==========================================================

  // Opens a file at specified |path| for reading, writing or both as indicated
  // by |mode|. The |disposition| specifies how the file must be opened/created:
  //  - OPEN_EXISTING   - opens the existing file and keeps its content intact.
  //                      The seek pointer is at the beginning of the file.
  //  - CREATE_ALWAYS   - creates the file always. If it exists, the file is
  //                      truncated.
  //  - CREATE_NEW_ONLY - creates a new file only if it doesn't exist. Fails
  //                      otherwise. This can be useful for creating lock files.
  //  - TRUNCATE_EXISTING - opens existing file and truncates it to zero length.
  //                       Fails if the file doesn't already exist.
  // If successful, the open file stream is returned. Otherwise returns the
  // stream pointer containing nullptr and fills in the details of the error
  // in |error| object, if provided.
  static StreamPtr Open(const base::FilePath& path,
                        AccessMode mode,
                        Disposition disposition,
                        ErrorPtr* error);

  // Creates a temporary unnamed file and returns a stream to it. The file will
  // be deleted when the stream is destroyed.
  static StreamPtr CreateTemporary(ErrorPtr* error);

  // Creates a file stream based on existing file descriptor. The file
  // descriptor will be set into non-blocking mode and will be owned by the
  // resulting stream (and closed when the stream is destroyed).
  // If the function fails, returns a null stream pointer and sets the error
  // details to |error| object. Also note that it is the caller's responsibility
  // to close the file descriptor if this function fails, since the stream
  // hasn't been created yet and didn't take ownership of the file descriptor.
  // |own_descriptor| indicates whether the stream must close the underlying
  // file descriptor when its CloseBlocking() method is called. This should be
  // set to false for file descriptors that shouldn't be closed (e.g. stdin).
  static StreamPtr FromFileDescriptor(int file_descriptor,
                                      bool own_descriptor,
                                      ErrorPtr* error);

  // == Stream capabilities ===================================================
  bool IsOpen() const override;
  bool CanRead() const override;
  bool CanWrite() const override;
  bool CanSeek() const override;
  bool CanGetSize() const override;

  // == Stream size operations ================================================
  uint64_t GetSize() const override;
  bool SetSizeBlocking(uint64_t size, ErrorPtr* error) override;
  uint64_t GetRemainingSize() const override;

  // == Seek operations =======================================================
  uint64_t GetPosition() const override;
  bool Seek(int64_t offset,
            Whence whence,
            uint64_t* new_position,
            ErrorPtr* error) override;

  // == Read operations =======================================================
  bool ReadNonBlocking(void* buffer,
                       size_t size_to_read,
                       size_t* size_read,
                       bool* end_of_stream,
                       ErrorPtr* error) override;

  // == Write operations ======================================================
  bool WriteNonBlocking(const void* buffer,
                        size_t size_to_write,
                        size_t* size_written,
                        ErrorPtr* error) override;

  // == Finalizing/closing streams  ===========================================
  bool FlushBlocking(ErrorPtr* error) override;
  bool CloseBlocking(ErrorPtr* error) override;

  // == Data availability monitoring ==========================================

  // Override for Stream::WaitForData to start watching the associated file
  // descriptor for non-blocking read/write operations.
  bool WaitForData(AccessMode mode,
                   const base::Callback<void(AccessMode)>& callback,
                   ErrorPtr* error) override;

  // Runs select() on the file descriptor to wait until we can do non-blocking
  // I/O on it.
  bool WaitForDataBlocking(AccessMode in_mode,
                           base::TimeDelta timeout,
                           AccessMode* out_mode,
                           ErrorPtr* error) override;

  // Cancels pending asynchronous read/write operations.
  void CancelPendingAsyncOperations() override;

 private:
  friend class FileStreamTest;

  // Internal constructor used by the factory methods Open(), CreateTemporary(),
  // and FromFileDescriptor().
  FileStream(std::unique_ptr<FileDescriptorInterface> fd_interface,
             AccessMode mode);
  FileStream(const FileStream&) = delete;
  FileStream& operator=(const FileStream&) = delete;

  // Wrapper for the file descriptor. Used in testing to mock out the real
  // file system APIs.
  std::unique_ptr<FileDescriptorInterface> fd_interface_;

  // The access mode this stream is open with.
  AccessMode access_mode_{AccessMode::READ_WRITE};

  // Set to false for streams that are guaranteed non-seekable.
  bool seekable_{true};

  // Set to false for streams that have unknown size.
  bool can_get_size_{false};
};

}  // namespace brillo

#endif  // LIBBRILLO_BRILLO_STREAMS_FILE_STREAM_H_
