// Copyright 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 DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_MAC_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_MAC_H_

#include <queue>
#include <string>

#import <IOBluetooth/IOBluetooth.h>
#import <IOKit/IOReturn.h>
#include <stddef.h>

#include "base/mac/scoped_nsobject.h"
#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_socket.h"
#include "device/bluetooth/bluetooth_uuid.h"

@class BluetoothRfcommConnectionListener;
@class BluetoothL2capConnectionListener;

namespace net {
class IOBuffer;
class IOBufferWithSize;
}

namespace device {

class BluetoothAdapterMac;
class BluetoothChannelMac;

// Implements the BluetoothSocket class for the Mac OS X platform.
class BluetoothSocketMac : public BluetoothSocket {
 public:
  static scoped_refptr<BluetoothSocketMac> CreateSocket();

  // Connects this socket to the service on |device| published as UUID |uuid|.
  // The underlying protocol and PSM or Channel is obtained through service
  // discovery. On a successful connection, the socket properties will be
  // updated and |success_callback| called. On failure, |error_callback| will be
  // called with a message explaining the cause of failure.
  void Connect(IOBluetoothDevice* device,
               const BluetoothUUID& uuid,
               const base::Closure& success_callback,
               const ErrorCompletionCallback& error_callback);

  // Listens for incoming RFCOMM connections using this socket: Publishes an
  // RFCOMM service on the |adapter| as UUID |uuid| with Channel
  // |options.channel|, or an automatically allocated Channel if
  // |options.channel| is left null. The service is published with English name
  // |options.name| if that is non-null. |success_callback| will be called if
  // the service is successfully registered, |error_callback| on failure with a
  // message explaining the cause.
  void ListenUsingRfcomm(scoped_refptr<BluetoothAdapterMac> adapter,
                         const BluetoothUUID& uuid,
                         const BluetoothAdapter::ServiceOptions& options,
                         const base::Closure& success_callback,
                         const ErrorCompletionCallback& error_callback);

  // Listens for incoming L2CAP connections using this socket: Publishes an
  // L2CAP service on the |adapter| as UUID |uuid| with PSM |options.psm|, or an
  // automatically allocated PSM if |options.psm| is left null. The service is
  // published with English name |options.name| if that is non-null.
  // |success_callback| will be called if the service is successfully
  // registered, |error_callback| on failure with a message explaining the
  // cause.
  void ListenUsingL2cap(scoped_refptr<BluetoothAdapterMac> adapter,
                        const BluetoothUUID& uuid,
                        const BluetoothAdapter::ServiceOptions& options,
                        const base::Closure& success_callback,
                        const ErrorCompletionCallback& error_callback);

  // BluetoothSocket:
  void Close() override;
  void Disconnect(const base::Closure& callback) override;
  void Receive(int /* buffer_size */,
               const ReceiveCompletionCallback& success_callback,
               const ReceiveErrorCompletionCallback& error_callback) override;
  void Send(scoped_refptr<net::IOBuffer> buffer,
            int buffer_size,
            const SendCompletionCallback& success_callback,
            const ErrorCompletionCallback& error_callback) override;
  void Accept(const AcceptCompletionCallback& success_callback,
              const ErrorCompletionCallback& error_callback) override;

  // Callback that is invoked when the OS completes an SDP query.
  // |status| is the returned status from the SDP query, |device| is the
  // IOBluetoothDevice for which the query was made. The remaining
  // parameters are those from |Connect()|.
  void OnSDPQueryComplete(
      IOReturn status,
      IOBluetoothDevice* device,
      const base::Closure& success_callback,
      const ErrorCompletionCallback& error_callback);

  // Called by BluetoothRfcommConnectionListener and
  // BluetoothL2capConnectionListener.
  void OnChannelOpened(scoped_ptr<BluetoothChannelMac> channel);

  // Called by |channel_|.
  // Note: OnChannelOpenComplete might be called before the |channel_| is set.
  void OnChannelOpenComplete(const std::string& device_address,
                             IOReturn status);
  void OnChannelClosed();
  void OnChannelDataReceived(void* data, size_t length);
  void OnChannelWriteComplete(void* refcon, IOReturn status);

 private:
  struct AcceptRequest {
    AcceptRequest();
    ~AcceptRequest();

    AcceptCompletionCallback success_callback;
    ErrorCompletionCallback error_callback;
  };

  struct SendRequest {
    SendRequest();
    ~SendRequest();
    int buffer_size;
    SendCompletionCallback success_callback;
    ErrorCompletionCallback error_callback;
    IOReturn status;
    int active_async_writes;
    bool error_signaled;
  };

  struct ReceiveCallbacks {
    ReceiveCallbacks();
    ~ReceiveCallbacks();
    ReceiveCompletionCallback success_callback;
    ReceiveErrorCompletionCallback error_callback;
  };

  struct ConnectCallbacks {
    ConnectCallbacks();
    ~ConnectCallbacks();
    base::Closure success_callback;
    ErrorCompletionCallback error_callback;
  };

  BluetoothSocketMac();
  ~BluetoothSocketMac() override;

  // Accepts a single incoming connection.
  void AcceptConnectionRequest();

  void ReleaseChannel();
  void ReleaseListener();

  bool is_connecting() const { return !!connect_callbacks_; }

  // Used to verify that all methods are called on the same thread.
  base::ThreadChecker thread_checker_;

  // Adapter the socket is registered against. This is only present when the
  // socket is listening.
  scoped_refptr<BluetoothAdapterMac> adapter_;

  // UUID of the profile being connected to, or that the socket is listening on.
  device::BluetoothUUID uuid_;

  // Simple helpers that register for OS notifications and forward them to
  // |this| profile.
  base::scoped_nsobject<BluetoothRfcommConnectionListener>
      rfcomm_connection_listener_;
  base::scoped_nsobject<BluetoothL2capConnectionListener>
      l2cap_connection_listener_;

  // A handle to the service record registered in the system SDP server.
  // Used to eventually unregister the service.
  BluetoothSDPServiceRecordHandle service_record_handle_;

  // The channel used to issue commands.
  scoped_ptr<BluetoothChannelMac> channel_;

  // Connection callbacks -- when a pending async connection is active.
  scoped_ptr<ConnectCallbacks> connect_callbacks_;

  // Packets received while there is no pending "receive" callback.
  std::queue<scoped_refptr<net::IOBufferWithSize> > receive_queue_;

  // Receive callbacks -- when a receive call is active.
  scoped_ptr<ReceiveCallbacks> receive_callbacks_;

  // Send queue -- one entry per pending send operation.
  std::queue<linked_ptr<SendRequest>> send_queue_;

  // The pending request to an Accept() call, or null if there is no pending
  // request.
  scoped_ptr<AcceptRequest> accept_request_;

  // Queue of incoming connections.
  std::queue<linked_ptr<BluetoothChannelMac>> accept_queue_;

  DISALLOW_COPY_AND_ASSIGN(BluetoothSocketMac);
};

}  // namespace device

#endif  // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_MAC_H_
