/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_RTC_BASE_WIN32SOCKETSERVER_H_
#define WEBRTC_RTC_BASE_WIN32SOCKETSERVER_H_

#if defined(WEBRTC_WIN)
#include "webrtc/rtc_base/asyncsocket.h"
#include "webrtc/rtc_base/criticalsection.h"
#include "webrtc/rtc_base/messagequeue.h"
#include "webrtc/rtc_base/socket.h"
#include "webrtc/rtc_base/socketfactory.h"
#include "webrtc/rtc_base/socketserver.h"
#include "webrtc/rtc_base/thread.h"
#include "webrtc/rtc_base/win32window.h"

namespace rtc {

///////////////////////////////////////////////////////////////////////////////
// Win32Socket
///////////////////////////////////////////////////////////////////////////////

class Win32Socket : public AsyncSocket {
 public:
  Win32Socket();
  virtual ~Win32Socket();

  bool CreateT(int family, int type);

  int Attach(SOCKET s);
  void SetTimeout(int ms);

  // AsyncSocket Interface
  virtual SocketAddress GetLocalAddress() const;
  virtual SocketAddress GetRemoteAddress() const;
  virtual int Bind(const SocketAddress& addr);
  virtual int Connect(const SocketAddress& addr);
  virtual int Send(const void *buffer, size_t length);
  virtual int SendTo(const void *buffer, size_t length, const SocketAddress& addr);
  virtual int Recv(void* buffer, size_t length, int64_t* timestamp);
  virtual int RecvFrom(void* buffer,
                       size_t length,
                       SocketAddress* out_addr,
                       int64_t* timestamp);
  virtual int Listen(int backlog);
  virtual Win32Socket *Accept(SocketAddress *out_addr);
  virtual int Close();
  virtual int GetError() const;
  virtual void SetError(int error);
  virtual ConnState GetState() const;
  virtual int GetOption(Option opt, int* value);
  virtual int SetOption(Option opt, int value);

 private:
  void CreateSink();
  bool SetAsync(int events);
  int DoConnect(const SocketAddress& addr);
  bool HandleClosed(int close_error);
  void PostClosed();
  void UpdateLastError();
  static int TranslateOption(Option opt, int* slevel, int* sopt);

  void OnSocketNotify(SOCKET socket, int event, int error);
  void OnDnsNotify(HANDLE task, int error);

  SOCKET socket_;
  int error_;
  ConnState state_;
  SocketAddress addr_;         // address that we connected to (see DoConnect)
  uint32_t connect_time_;
  bool closing_;
  int close_error_;

  class EventSink;
  friend class EventSink;
  EventSink * sink_;

  struct DnsLookup;
  DnsLookup * dns_;
};

///////////////////////////////////////////////////////////////////////////////
// Win32SocketServer
///////////////////////////////////////////////////////////////////////////////

class Win32SocketServer : public SocketServer {
 public:
  Win32SocketServer();
  virtual ~Win32SocketServer();

  void set_modeless_dialog(HWND hdlg) {
    hdlg_ = hdlg;
  }

  // SocketServer Interface
  virtual Socket* CreateSocket(int type);
  virtual Socket* CreateSocket(int family, int type);

  virtual AsyncSocket* CreateAsyncSocket(int type);
  virtual AsyncSocket* CreateAsyncSocket(int family, int type);

  virtual void SetMessageQueue(MessageQueue* queue);
  virtual bool Wait(int cms, bool process_io);
  virtual void WakeUp();

  void Pump();

  HWND handle() { return wnd_.handle(); }

 private:
  class MessageWindow : public Win32Window {
   public:
    explicit MessageWindow(Win32SocketServer* ss) : ss_(ss) {}
   private:
    virtual bool OnMessage(UINT msg, WPARAM wp, LPARAM lp, LRESULT& result);
    Win32SocketServer* ss_;
  };

  static const TCHAR kWindowName[];
  MessageQueue *message_queue_;
  MessageWindow wnd_;
  CriticalSection cs_;
  bool posted_;
  HWND hdlg_;
};

///////////////////////////////////////////////////////////////////////////////
// Win32Thread. Automatically pumps Windows messages.
///////////////////////////////////////////////////////////////////////////////

class Win32Thread : public Thread {
 public:
  explicit Win32Thread(SocketServer* ss) : Thread(ss),  id_(0) {}
  virtual ~Win32Thread() {
    Stop();
  }
  virtual void Run() {
    id_ = GetCurrentThreadId();
    Thread::Run();
    id_ = 0;
  }
  virtual void Quit() {
    PostThreadMessage(id_, WM_QUIT, 0, 0);
  }
 private:
  DWORD id_;
};

///////////////////////////////////////////////////////////////////////////////

}  // namespace rtc

#endif  // WEBRTC_WIN

#endif  // WEBRTC_RTC_BASE_WIN32SOCKETSERVER_H_
