// Copyright 2016 The Chromium 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 NET_LOG_FILE_NET_LOG_OBSERVER_H_
#define NET_LOG_FILE_NET_LOG_OBSERVER_H_

#include <limits>
#include <memory>

#include "base/files/file.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "net/base/net_export.h"
#include "net/log/net_log.h"

#if !defined(STARBOARD)

namespace base {
class Value;
class FilePath;
class SequencedTaskRunner;
}  // namespace base

namespace net {

class NetLogCaptureMode;

// FileNetLogObserver watches the NetLog event stream and sends all entries to
// a file.
//
// Consumers must call StartObserving before calling StopObserving, and must
// call each method exactly once in the lifetime of the observer.
//
// The log will not be completely written until StopObserving is called.
//
// When a file size limit is given, FileNetLogObserver will create temporary
// directory containing chunks of events. This is used to drop older events in
// favor of newer ones.
class NET_EXPORT FileNetLogObserver : public NetLog::ThreadSafeObserver {
 public:
  // Special value meaning "can use an unlimited number of bytes".
  static constexpr uint64_t kNoLimit = std::numeric_limits<uint64_t>::max();

  // Creates an instance of FileNetLogObserver that writes observed netlog
  // events to |log_path|.
  //
  // |log_path| is where the final log file will be written to. If a file
  // already exists at this path it will be overwritten. While logging is in
  // progress, events may be written to a like-named directory.
  //
  // |max_total_size| is the limit on how many bytes logging may consume on
  // disk. This is an approximate limit, and in practice FileNetLogObserver may
  // (slightly) exceed it. This may be set to kNoLimit to remove any size
  // restrictions.
  //
  // |constants| is an optional legend for decoding constant values used in
  // the log. It should generally be a modified version of GetNetConstants().
  // If not present, the output of GetNetConstants() will be used.
  static std::unique_ptr<FileNetLogObserver> CreateBounded(
      const base::FilePath& log_path,
      uint64_t max_total_size,
      std::unique_ptr<base::Value> constants);

  // Shortcut for calling CreateBounded() with kNoLimit.
  static std::unique_ptr<FileNetLogObserver> CreateUnbounded(
      const base::FilePath& log_path,
      std::unique_ptr<base::Value> constants);

  // Creates a bounded log that writes to a pre-existing file (truncating
  // it to start with, and closing it upon completion).  |inprogress_dir_path|
  // will be used as a scratch directory, for temporary files (with predictable
  // names).
  static std::unique_ptr<FileNetLogObserver> CreateBoundedPreExisting(
      const base::FilePath& inprogress_dir_path,
      base::File output_file,
      uint64_t max_total_size,
      std::unique_ptr<base::Value> constants);

  // Creates an unbounded log that writes to a pre-existing file (truncating
  // it to start with, and closing it upon completion).
  static std::unique_ptr<FileNetLogObserver> CreateUnboundedPreExisting(
      base::File output_file,
      std::unique_ptr<base::Value> constants);

  ~FileNetLogObserver() override;

  // Attaches this observer to |net_log| and begins observing events.
  void StartObserving(NetLog* net_log, NetLogCaptureMode capture_mode);

  // Stops observing net_log() and closes the output file(s). Must be called
  // after StartObserving. Should be called before destruction of the
  // FileNetLogObserver and the NetLog, or the NetLog files (except for an
  // externally provided output_file) will be deleted when the observer is
  // destroyed. Note that it is OK to destroy |this| immediately after calling
  // StopObserving() - the callback will still be called once the file writing
  // has completed.
  //
  // |polled_data| is an optional argument used to add additional network stack
  // state to the log.
  //
  // If non-null, |optional_callback| will be run on whichever thread
  // StopObserving() was called on once all file writing is complete and the
  // netlog files can be accessed safely.
  void StopObserving(std::unique_ptr<base::Value> polled_data,
                     base::OnceClosure optional_callback);

  // NetLog::ThreadSafeObserver
  void OnAddEntry(const NetLogEntry& entry) override;

  // Same as CreateBounded() but you can additionally specify
  // |total_num_event_files|.
  static std::unique_ptr<FileNetLogObserver> CreateBoundedForTests(
      const base::FilePath& log_path,
      uint64_t max_total_size,
      size_t total_num_event_files,
      std::unique_ptr<base::Value> constants);

 private:
  class WriteQueue;
  class FileWriter;

  static std::unique_ptr<FileNetLogObserver> CreateInternal(
      const base::FilePath& log_path,
      const base::FilePath& inprogress_dir_path,
      base::Optional<base::File> pre_existing_out_file,
      uint64_t max_total_size,
      size_t total_num_event_files,
      std::unique_ptr<base::Value> constants);

  FileNetLogObserver(scoped_refptr<base::SequencedTaskRunner> file_task_runner,
                     std::unique_ptr<FileWriter> file_writer,
                     scoped_refptr<WriteQueue> write_queue,
                     std::unique_ptr<base::Value> constants);

  scoped_refptr<base::SequencedTaskRunner> file_task_runner_;

  // The |write_queue_| object is shared between the file task runner and the
  // main thread, and should be alive for the entirety of the observer's
  // lifetime. It should be destroyed once both the observer has been destroyed
  // and all tasks posted to the file task runner have completed.
  scoped_refptr<WriteQueue> write_queue_;

  // The FileNetLogObserver is shared between the main thread and
  // |file_task_runner_|.
  //
  // Conceptually FileNetLogObserver owns it, however on destruction its
  // deletion is deferred until outstanding tasks on |file_task_runner_| have
  // finished (since it is posted using base::Unretained()).
  std::unique_ptr<FileWriter> file_writer_;

  DISALLOW_COPY_AND_ASSIGN(FileNetLogObserver);
};

}  // namespace net

#endif  // !defined(STARBOARD)

#endif  // NET_LOG_FILE_NET_LOG_OBSERVER_H_
