// Copyright 2013 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//
// FileReaderFactory is a factory class of FileReader and its subclass.
// You can register creator function of a special purpose FileReader subclass
// through Register. For registering creator function at the beginning of the
// program, FileReaderFactory is a singleton class.
// This class is thread-hostile.
//
// FileReader is a wrapper class of ScopedFd.
// Subclass of this class is made for giving a special behavior on reading.
// This class's thread safety is the same as scoped_fd.

#ifndef DEVTOOLS_GOMA_LIB_FILE_READER_H_
#define DEVTOOLS_GOMA_LIB_FILE_READER_H_

#include <memory>
#include <string>
#include <vector>

#include "lib/scoped_fd.h"
using std::string;

namespace devtools_goma {

class FileReader;

class FileReaderFactory {
 public:
  // A type to create an FileReader instance.
  // It returns NULL if it cannot handle the given |filename|.
  typedef std::unique_ptr<FileReader> (*CreateFunction)(const string& filename);

  // Returns a new instance of FileReader or its subclass.
  std::unique_ptr<FileReader> NewFileReader(const string& filename);

  // Registers the creator functions of FileReader or its subclass.
  static void Register(CreateFunction create);

  // Gets the singleton instance of FileReaderFactory.
  static FileReaderFactory* GetInstance();

 private:
  FileReaderFactory() {}

  // Deletes the singleton instance to be called by atexit.
  static void DeleteInstance();

  std::vector<CreateFunction> creators_;
  static FileReaderFactory* factory_;

  DISALLOW_COPY_AND_ASSIGN(FileReaderFactory);
};

// Wrapper class of ScopedFd.
// Subclass of this class is used for special treatment of files.
class FileReader {
 public:
  virtual ~FileReader() {}

  // Wrapper of ScopedFd's Read.
  // If |len| == 0, returns 0.
  virtual ssize_t Read(void* ptr, size_t len) {
    if (len == 0) {
      return 0;
    }
    return fd_.Read(ptr, len);
  }

  // Wrapper of ScopedFd's Seek.
  virtual off_t Seek(off_t offset, ScopedFd::Whence whence) const {
    return fd_.Seek(offset, whence);
  }

  // Wrapper of ScopedFd's valid.
  virtual bool valid() const {
    return fd_.valid();
  }

  // Wrapper of ScopedFd's GetFileSize.
  virtual bool GetFileSize(size_t* file_size) const {
    return fd_.GetFileSize(file_size);
  }

  // Copies data in |*buf| to |*ptr| with |*len|.
  // |*ptr| is automatically incremented and |*len| is automatically
  // decremented. Moved data in |*buf| is removed.
  // Returns the number of copied bytes.
  //
  // Note: if size of |*buf| is larger than |*len|, copy would happen,
  //       performance may suffer.
  static size_t FlushDataInBuffer(string* buf, void** ptr, size_t* len);

 protected:
  explicit FileReader(const string& filename)
      : fd_(ScopedFd::OpenForRead(filename)) {
  }

 private:
  // Returns an instance of FileReader.
  static std::unique_ptr<FileReader> Create(const string& filename) {
    return std::unique_ptr<FileReader>(new FileReader(filename));
  }

  ScopedFd fd_;

  friend class FileReaderFactory;
  DISALLOW_COPY_AND_ASSIGN(FileReader);
};

}  // namespace devtools_goma

#endif  // DEVTOOLS_GOMA_LIB_FILE_READER_H_
