// Copyright 2014 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.

#include "device/bluetooth/bluetooth_rfcomm_channel_mac.h"

#include "base/logging.h"
#include "device/bluetooth/bluetooth_device_mac.h"
#include "device/bluetooth/bluetooth_socket_mac.h"

// A simple delegate class for an open RFCOMM channel that forwards methods to
// its wrapped |channel_|.
@interface BluetoothRfcommChannelDelegate
    : NSObject <IOBluetoothRFCOMMChannelDelegate> {
 @private
  device::BluetoothRfcommChannelMac* channel_;  // weak
}

- (id)initWithChannel:(device::BluetoothRfcommChannelMac*)channel;

@end

@implementation BluetoothRfcommChannelDelegate

- (id)initWithChannel:(device::BluetoothRfcommChannelMac*)channel {
  if ((self = [super init]))
    channel_ = channel;

  return self;
}

- (void)rfcommChannelOpenComplete:(IOBluetoothRFCOMMChannel*)rfcommChannel
                           status:(IOReturn)error {
  channel_->OnChannelOpenComplete(rfcommChannel, error);
}

- (void)rfcommChannelWriteComplete:(IOBluetoothRFCOMMChannel*)rfcommChannel
                            refcon:(void*)refcon
                            status:(IOReturn)error {
  channel_->OnChannelWriteComplete(rfcommChannel, refcon, error);
}

- (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel
                     data:(void*)dataPointer
                   length:(size_t)dataLength {
  channel_->OnChannelDataReceived(rfcommChannel, dataPointer, dataLength);
}

- (void)rfcommChannelClosed:(IOBluetoothRFCOMMChannel*)rfcommChannel {
  channel_->OnChannelClosed(rfcommChannel);
}

@end

namespace device {

BluetoothRfcommChannelMac::BluetoothRfcommChannelMac(
    BluetoothSocketMac* socket,
    IOBluetoothRFCOMMChannel* channel)
    : channel_(channel),
      delegate_(nil) {
  SetSocket(socket);
}

BluetoothRfcommChannelMac::~BluetoothRfcommChannelMac() {
  [channel_ setDelegate:nil];
  [channel_ closeChannel];
}

// static
scoped_ptr<BluetoothRfcommChannelMac> BluetoothRfcommChannelMac::OpenAsync(
    BluetoothSocketMac* socket,
    IOBluetoothDevice* device,
    BluetoothRFCOMMChannelID channel_id,
    IOReturn* status) {
  DCHECK(socket);
  scoped_ptr<BluetoothRfcommChannelMac> channel(
      new BluetoothRfcommChannelMac(socket, nil));

  // Retain the delegate, because IOBluetoothDevice's
  // |-openRFCOMMChannelAsync:withChannelID:delegate:| assumes that it can take
  // ownership of the delegate without calling |-retain| on it...
  DCHECK(channel->delegate_);
  [channel->delegate_ retain];
  IOBluetoothRFCOMMChannel* rfcomm_channel;
  *status = [device openRFCOMMChannelAsync:&rfcomm_channel
                             withChannelID:channel_id
                                  delegate:channel->delegate_];
  if (*status == kIOReturnSuccess) {
    // Note: No need to retain the |rfcomm_channel| -- the returned channel is
    // already retained.
    channel->channel_.reset(rfcomm_channel);
  } else {
    channel.reset();
  }

  return channel.Pass();
}

void BluetoothRfcommChannelMac::SetSocket(BluetoothSocketMac* socket) {
  BluetoothChannelMac::SetSocket(socket);
  if (!this->socket())
    return;

  // Now that the socket is set, it's safe to associate a delegate, which can
  // call back to the socket.
  DCHECK(!delegate_);
  delegate_.reset(
      [[BluetoothRfcommChannelDelegate alloc] initWithChannel:this]);
  [channel_ setDelegate:delegate_];
}

IOBluetoothDevice* BluetoothRfcommChannelMac::GetDevice() {
  return [channel_ getDevice];
}

uint16_t BluetoothRfcommChannelMac::GetOutgoingMTU() {
  return [channel_ getMTU];
}

IOReturn BluetoothRfcommChannelMac::WriteAsync(void* data,
                                               uint16_t length,
                                               void* refcon) {
  DCHECK_LE(length, GetOutgoingMTU());
  return [channel_ writeAsync:data length:length refcon:refcon];
}

void BluetoothRfcommChannelMac::OnChannelOpenComplete(
    IOBluetoothRFCOMMChannel* channel,
    IOReturn status) {
  if (channel_) {
    DCHECK_EQ(channel_, channel);
  } else {
    // The (potentially) asynchronous connection occurred synchronously.
    // Should only be reachable from OpenAsync().
    DCHECK_EQ(status, kIOReturnSuccess);
  }

  socket()->OnChannelOpenComplete(
      BluetoothDeviceMac::GetDeviceAddress([channel getDevice]), status);
}

void BluetoothRfcommChannelMac::OnChannelClosed(
    IOBluetoothRFCOMMChannel* channel) {
  DCHECK_EQ(channel_, channel);
  socket()->OnChannelClosed();
}

void BluetoothRfcommChannelMac::OnChannelDataReceived(
    IOBluetoothRFCOMMChannel* channel,
    void* data,
    size_t length) {
  DCHECK_EQ(channel_, channel);
  socket()->OnChannelDataReceived(data, length);
}

void BluetoothRfcommChannelMac::OnChannelWriteComplete(
    IOBluetoothRFCOMMChannel* channel,
    void* refcon,
    IOReturn status) {
  // Note: We use "CHECK" below to ensure we never run into unforeseen
  // occurrences of asynchronous callbacks, which could lead to data
  // corruption.
  CHECK_EQ(channel_, channel);
  socket()->OnChannelWriteComplete(refcon, status);
}

}  // namespace device
