// Copyright (c) 2012 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_WEBSOCKETS_WEBSOCKET_JOB_H_
#define NET_WEBSOCKETS_WEBSOCKET_JOB_H_

#include <deque>
#include <string>
#include <vector>

#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time.h"
#include "base/timer.h"
#include "net/base/address_list.h"
#include "net/base/completion_callback.h"
#include "net/socket_stream/socket_stream_job.h"

class GURL;

namespace net {

class DrainableIOBuffer;
class SSLInfo;
class WebSocketHandshakeRequestHandler;
class WebSocketHandshakeResponseHandler;

// WebSocket protocol specific job on SocketStream.
// It captures WebSocket handshake message and handles cookie operations.
// Chrome security policy doesn't allow renderer process (except dev tools)
// see HttpOnly cookies, so it injects cookie header in handshake request and
// strips set-cookie headers in handshake response.
// TODO(ukai): refactor websocket.cc to use this.
class NET_EXPORT WebSocketJob
    : public SocketStreamJob,
      public SocketStream::Delegate {
 public:
  // This is state of WebSocket, not SocketStream.
  enum State {
    INITIALIZED = -1,
    CONNECTING = 0,
    OPEN = 1,
    SEND_CLOSED = 2,  // A Close frame has been sent but not received.
    RECV_CLOSED = 3,  // Used briefly between receiving a Close frame and
                      // sending the response. Once the response is sent, the
                      // state changes to CLOSED.
    CLOSE_WAIT = 4,   // The Closing Handshake has completed, but the remote
                      // server has not yet closed the connection.
    CLOSED = 5,       // The Closing Handshake has completed and the connection
                      // has been closed; or the connection is failed.
  };

  explicit WebSocketJob(SocketStream::Delegate* delegate);

  static void EnsureInit();

  State state() const { return state_; }
  virtual void Connect() OVERRIDE;
  virtual bool SendData(const char* data, int len) OVERRIDE;
  virtual void Close() OVERRIDE;
  virtual void RestartWithAuth(const AuthCredentials& credentials) OVERRIDE;
  virtual void DetachDelegate() OVERRIDE;

  // SocketStream::Delegate methods.
  virtual int OnStartOpenConnection(
      SocketStream* socket, const CompletionCallback& callback) OVERRIDE;
  virtual void OnConnected(SocketStream* socket,
                           int max_pending_send_allowed) OVERRIDE;
  virtual void OnSentData(SocketStream* socket, int amount_sent) OVERRIDE;
  virtual void OnReceivedData(SocketStream* socket,
                              const char* data,
                              int len) OVERRIDE;
  virtual void OnClose(SocketStream* socket) OVERRIDE;
  virtual void OnAuthRequired(
      SocketStream* socket, AuthChallengeInfo* auth_info) OVERRIDE;
  virtual void OnSSLCertificateError(SocketStream* socket,
                                     const SSLInfo& ssl_info,
                                     bool fatal) OVERRIDE;
  virtual void OnError(const SocketStream* socket, int error) OVERRIDE;

  WebSocketHandshakeResponseHandler* GetHandshakeResponse() {
    return handshake_response_.get();
  }

  void SetState(const State new_state) {
    DCHECK_GE(new_state, state_);  // states should only move forward.
    state_ = new_state;
  }

 private:
  friend class WebSocketThrottle;
  virtual ~WebSocketJob();

  bool SendHandshakeRequest(const char* data, int len);
  void AddCookieHeaderAndSend();
  void LoadCookieCallback(const std::string& cookie);

  void OnSentHandshakeRequest(SocketStream* socket, int amount_sent);
  void OnReceivedHandshakeResponse(
      SocketStream* socket, const char* data, int len);
  void SaveCookiesAndNotifyHeaderComplete();
  void SaveNextCookie();
  void SaveCookieCallback(bool cookie_status);
  void DoSendData();

  GURL GetURLForCookies() const;

  const AddressList& address_list() const;
  void SetWaiting();
  bool IsWaiting() const;
  void Wakeup();
  void RetryPendingIO();
  void CompleteIO(int result);

  bool SendDataInternal(const char* data, int length);
  void CloseInternal();
  void SendPending();
  void CloseTimeout();
  void StopTimer(base::WaitableEvent* timer_stop_event);

  void WaitForSocketClose();
  void DelayedClose();

  SocketStream::Delegate* delegate_;
  State state_;
  bool waiting_;
  AddressList addresses_;
  CompletionCallback callback_;  // for throttling.

  scoped_ptr<WebSocketHandshakeRequestHandler> handshake_request_;
  scoped_ptr<WebSocketHandshakeResponseHandler> handshake_response_;

  bool started_to_send_handshake_request_;
  size_t handshake_request_sent_;

  std::vector<std::string> response_cookies_;
  size_t response_cookies_save_index_;

  std::deque<scoped_refptr<IOBufferWithSize> > send_buffer_queue_;
  scoped_refptr<DrainableIOBuffer> current_send_buffer_;
  std::vector<char> received_data_after_handshake_;

  std::string challenge_;

  base::TimeDelta closing_handshake_timeout_;
  scoped_ptr<base::OneShotTimer<WebSocketJob> > close_timer_;

  base::WeakPtrFactory<WebSocketJob> weak_ptr_factory_;
  base::WeakPtrFactory<WebSocketJob> weak_ptr_factory_for_send_pending_;

  DISALLOW_COPY_AND_ASSIGN(WebSocketJob);
};

}  // namespace

#endif  // NET_WEBSOCKETS_WEBSOCKET_JOB_H_
