//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.

#ifndef ROCKSDB_LITE

#pragma once
#include <string>
#include "rocksdb/env.h"
#include "rocksdb/options.h"
#include "rocksdb/table_properties.h"
#include "rocksdb/types.h"

namespace rocksdb {

class Comparator;

// ExternalSstFileInfo include information about sst files created
// using SstFileWriter
struct ExternalSstFileInfo {
  ExternalSstFileInfo() {}
  ExternalSstFileInfo(const std::string& _file_path,
                      const std::string& _smallest_key,
                      const std::string& _largest_key,
                      SequenceNumber _sequence_number, uint64_t _file_size,
                      int32_t _num_entries, int32_t _version)
      : file_path(_file_path),
        smallest_key(_smallest_key),
        largest_key(_largest_key),
        sequence_number(_sequence_number),
        file_size(_file_size),
        num_entries(_num_entries),
        version(_version) {}

  std::string file_path;           // external sst file path
  std::string smallest_key;        // smallest user key in file
  std::string largest_key;         // largest user key in file
  SequenceNumber sequence_number;  // sequence number of all keys in file
  uint64_t file_size;              // file size in bytes
  uint64_t num_entries;            // number of entries in file
  int32_t version;                 // file version
};

// SstFileWriter is used to create sst files that can be added to database later
// All keys in files generated by SstFileWriter will have sequence number = 0
class SstFileWriter {
 public:
  // User can pass `column_family` to specify that the the generated file will
  // be ingested into this column_family, note that passing nullptr means that
  // the column_family is unknown.
  // If invalidate_page_cache is set to true, SstFileWriter will give the OS a
  // hint that this file pages is not needed everytime we write 1MB to the file
  SstFileWriter(const EnvOptions& env_options, const Options& options,
                ColumnFamilyHandle* column_family = nullptr,
                bool invalidate_page_cache = true)
      : SstFileWriter(env_options, options, options.comparator, column_family,
                      invalidate_page_cache) {}

  // Deprecated API
  SstFileWriter(const EnvOptions& env_options, const Options& options,
                const Comparator* user_comparator,
                ColumnFamilyHandle* column_family = nullptr,
                bool invalidate_page_cache = true);

  ~SstFileWriter();

  // Prepare SstFileWriter to write into file located at "file_path".
  Status Open(const std::string& file_path);

  // Add key, value to currently opened file
  // REQUIRES: key is after any previously added key according to comparator.
  Status Add(const Slice& user_key, const Slice& value);

  // Finalize writing to sst file and close file.
  //
  // An optional ExternalSstFileInfo pointer can be passed to the function
  // which will be populated with information about the created sst file
  Status Finish(ExternalSstFileInfo* file_info = nullptr);

  // Return the current file size.
  uint64_t FileSize();

 private:
  void InvalidatePageCache(bool closing);

  struct Rep;
  Rep* rep_;
};
}  // namespace rocksdb

#endif  // !ROCKSDB_LITE
