// Copyright (c) 2013 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_URL_REQUEST_URL_FETCHER_RESPONSE_WRITER_H_
#define NET_URL_REQUEST_URL_FETCHER_RESPONSE_WRITER_H_

#include <string>

#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"

namespace base {
class SequencedTaskRunner;
}  // namespace base

namespace net {

class DrainableIOBuffer;
class FileStream;
class IOBuffer;
class URLFetcherFileWriter;
class URLFetcherStringWriter;

// This class encapsulates all state involved in writing URLFetcher response
// bytes to the destination.
class NET_EXPORT URLFetcherResponseWriter {
 public:
  virtual ~URLFetcherResponseWriter() {}

  // Initializes this instance. If ERR_IO_PENDING is returned, |callback| will
  // be run later with the result. Calling this method again after a
  // Initialize() success results in discarding already written data.
  virtual int Initialize(const CompletionCallback& callback) = 0;

  // Writes |num_bytes| bytes in |buffer|, and returns the number of bytes
  // written or an error code. If ERR_IO_PENDING is returned, |callback| will be
  // run later with the result.
  virtual int Write(IOBuffer* buffer,
                    int num_bytes,
                    const CompletionCallback& callback) = 0;

  // Finishes writing. If ERR_IO_PENDING is returned, |callback| will be run
  // later with the result.
  virtual int Finish(const CompletionCallback& callback) = 0;

  // Returns this instance's pointer as URLFetcherStringWriter when possible.
  virtual URLFetcherStringWriter* AsStringWriter();

  // Returns this instance's pointer as URLFetcherFileWriter when possible.
  virtual URLFetcherFileWriter* AsFileWriter();
};

// URLFetcherResponseWriter implementation for std::string.
class NET_EXPORT URLFetcherStringWriter : public URLFetcherResponseWriter {
 public:
  URLFetcherStringWriter();
  virtual ~URLFetcherStringWriter();

  const std::string& data() const { return data_; }

  // URLFetcherResponseWriter overrides:
  virtual int Initialize(const CompletionCallback& callback) OVERRIDE;
  virtual int Write(IOBuffer* buffer,
                    int num_bytes,
                    const CompletionCallback& callback) OVERRIDE;
  virtual int Finish(const CompletionCallback& callback) OVERRIDE;
  virtual URLFetcherStringWriter* AsStringWriter() OVERRIDE;

 private:
  std::string data_;

  DISALLOW_COPY_AND_ASSIGN(URLFetcherStringWriter);
};

// URLFetcherResponseWriter implementation for files.
class NET_EXPORT URLFetcherFileWriter : public URLFetcherResponseWriter {
 public:
  // |file_path| is used as the destination path. If |file_path| is empty,
  // Initialize() will create a temporary file.
  URLFetcherFileWriter(
      scoped_refptr<base::SequencedTaskRunner> file_task_runner,
      const base::FilePath& file_path);
  virtual ~URLFetcherFileWriter();

  const base::FilePath& file_path() const { return file_path_; }

  // URLFetcherResponseWriter overrides:
  virtual int Initialize(const CompletionCallback& callback) OVERRIDE;
  virtual int Write(IOBuffer* buffer,
                    int num_bytes,
                    const CompletionCallback& callback) OVERRIDE;
  virtual int Finish(const CompletionCallback& callback) OVERRIDE;
  virtual URLFetcherFileWriter* AsFileWriter() OVERRIDE;

  // Drops ownership of the file at |file_path_|.
  // This class will not delete it or write to it again.
  void DisownFile();

 private:
  // Called when a write has been done.
  void DidWrite(const CompletionCallback& callback, int result);

  // Closes the file if it is open and then delete it.
  void CloseAndDeleteFile();

  // Callback which gets the result of a temporary file creation.
  void DidCreateTempFile(const CompletionCallback& callback,
                         base::FilePath* temp_file_path,
                         bool success);

  // Callback which gets the result of FileStream::Open.
  void DidOpenFile(const CompletionCallback& callback,
                   int result);

  // Callback which gets the result of closing a file.
  void CloseComplete(const CompletionCallback& callback, int result);

  // Task runner on which file operations should happen.
  scoped_refptr<base::SequencedTaskRunner> file_task_runner_;

  // Destination file path.
  // Initialize() creates a temporary file if this variable is empty.
  base::FilePath file_path_;

  // True when this instance is responsible to delete the file at |file_path_|.
  bool owns_file_;

  scoped_ptr<FileStream> file_stream_;

  // Callbacks are created for use with base::FileUtilProxy.
  base::WeakPtrFactory<URLFetcherFileWriter> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(URLFetcherFileWriter);
};

}  // namespace net

#endif  // NET_URL_REQUEST_URL_FETCHER_RESPONSE_WRITER_H_
