/*
 * libjingle
 * Copyright 2004--2005, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products 
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "talk/p2p/base/transportchannelproxy.h"
#include "talk/base/common.h"
#include "talk/p2p/base/transport.h"
#include "talk/p2p/base/transportchannelimpl.h"

namespace cricket {

TransportChannelProxy::TransportChannelProxy(const std::string& name,
                                             const std::string& content_type)
    : TransportChannel(name, content_type), impl_(NULL), owner_(false) {
}

TransportChannelProxy::~TransportChannelProxy() {
  if (owner_ && impl_)
    impl_->GetTransport()->DestroyChannel(impl_->name());
}

void TransportChannelProxy::SetImplementation(TransportChannelImpl* impl,
                                              bool owner) {
  impl_ = impl;
  impl_->SignalReadableState.connect(
      this, &TransportChannelProxy::OnReadableState);
  impl_->SignalWritableState.connect(
      this, &TransportChannelProxy::OnWritableState);
  impl_->SignalReadPacket.connect(this, &TransportChannelProxy::OnReadPacket);
  impl_->SignalRouteChange.connect(this, &TransportChannelProxy::OnRouteChange);
  for (OptionList::iterator it = pending_options_.begin();
       it != pending_options_.end();
       ++it) {
    impl_->SetOption(it->first, it->second);
  }
  pending_options_.clear();
  owner_ = owner;
}

int TransportChannelProxy::SendPacket(const char* data, size_t len) {
  // Fail if we don't have an impl yet.
  return (impl_) ? impl_->SendPacket(data, len) : -1;
}

int TransportChannelProxy::SetOption(talk_base::Socket::Option opt, int value) {
  if (impl_)
    return impl_->SetOption(opt, value);
  pending_options_.push_back(OptionPair(opt, value));
  return 0;
}

int TransportChannelProxy::GetError() {
  ASSERT(impl_ != NULL);  // should not be used until channel is writable
  return impl_->GetError();
}

P2PTransportChannel* TransportChannelProxy::GetP2PChannel() {
  if (impl_) {
      return impl_->GetP2PChannel();
  }
  return NULL;
}

void TransportChannelProxy::OnReadableState(TransportChannel* channel) {
  ASSERT(channel == impl_);
  set_readable(impl_->readable());
}

void TransportChannelProxy::OnWritableState(TransportChannel* channel) {
  ASSERT(channel == impl_);
  set_writable(impl_->writable());
}

void TransportChannelProxy::OnReadPacket(TransportChannel* channel,
                                         const char* data, size_t size) {
  ASSERT(channel == impl_);
  SignalReadPacket(this, data, size);
}

void TransportChannelProxy::OnRouteChange(TransportChannel* channel,
                                          const Candidate& candidate) {
  ASSERT(channel == impl_);
  SignalRouteChange(this, candidate);
}

}  // namespace cricket
