/*
 * libjingle
 * Copyright 2004--2008, 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 "pseudotcpchannel.h"
#include "talk/p2p/base/constants.h"
#include "talk/p2p/base/transportchannel.h"
#include "webrtc/libjingle/xmllite/xmlelement.h"
#include "tunnelsessionclient.h"
#include "webrtc/base/basicdefs.h"
#include "webrtc/base/basictypes.h"
#include "webrtc/base/common.h"
#include "webrtc/base/helpers.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/stringutils.h"

namespace cricket {

const char NS_TUNNEL[] = "http://www.google.com/talk/tunnel";
const buzz::StaticQName QN_TUNNEL_DESCRIPTION = { NS_TUNNEL, "description" };
const buzz::StaticQName QN_TUNNEL_TYPE = { NS_TUNNEL, "type" };
const char CN_TUNNEL[] = "tunnel";

enum {
  MSG_CLOCK = 1,
  MSG_DESTROY,
  MSG_TERMINATE,
  MSG_EVENT,
  MSG_CREATE_TUNNEL,
};

struct EventData : public rtc::MessageData {
  int event, error;
  EventData(int ev, int err = 0) : event(ev), error(err) { }
};

struct CreateTunnelData : public rtc::MessageData {
  buzz::Jid jid;
  std::string description;
  rtc::Thread* thread;
  rtc::StreamInterface* stream;
};

extern const rtc::ConstantLabel SESSION_STATES[];

const rtc::ConstantLabel SESSION_STATES[] = {
  KLABEL(Session::STATE_INIT),
  KLABEL(Session::STATE_SENTINITIATE),
  KLABEL(Session::STATE_RECEIVEDINITIATE),
  KLABEL(Session::STATE_SENTACCEPT),
  KLABEL(Session::STATE_RECEIVEDACCEPT),
  KLABEL(Session::STATE_SENTMODIFY),
  KLABEL(Session::STATE_RECEIVEDMODIFY),
  KLABEL(Session::STATE_SENTREJECT),
  KLABEL(Session::STATE_RECEIVEDREJECT),
  KLABEL(Session::STATE_SENTREDIRECT),
  KLABEL(Session::STATE_SENTTERMINATE),
  KLABEL(Session::STATE_RECEIVEDTERMINATE),
  KLABEL(Session::STATE_INPROGRESS),
  KLABEL(Session::STATE_DEINIT),
  LASTLABEL
};

///////////////////////////////////////////////////////////////////////////////
// TunnelContentDescription
///////////////////////////////////////////////////////////////////////////////

struct TunnelContentDescription : public ContentDescription {
  std::string description;

  TunnelContentDescription(const std::string& desc) : description(desc) { }
  virtual ContentDescription* Copy() const {
    return new TunnelContentDescription(*this);
  }
};

///////////////////////////////////////////////////////////////////////////////
// TunnelSessionClientBase
///////////////////////////////////////////////////////////////////////////////

TunnelSessionClientBase::TunnelSessionClientBase(const buzz::Jid& jid,
                                SessionManager* manager, const std::string &ns)
  : jid_(jid), session_manager_(manager), namespace_(ns), shutdown_(false) {
  session_manager_->AddClient(namespace_, this);
}

TunnelSessionClientBase::~TunnelSessionClientBase() {
  shutdown_ = true;
  for (std::vector<TunnelSession*>::iterator it = sessions_.begin();
       it != sessions_.end();
       ++it) {
     Session* session = (*it)->ReleaseSession(true);
     session_manager_->DestroySession(session);
  }
  session_manager_->RemoveClient(namespace_);
}

void TunnelSessionClientBase::OnSessionCreate(Session* session, bool received) {
  LOG(LS_INFO) << "TunnelSessionClientBase::OnSessionCreate: received=" 
               << received;
  ASSERT(session_manager_->signaling_thread()->IsCurrent());
  if (received)
    sessions_.push_back(
        MakeTunnelSession(session, rtc::Thread::Current(), RESPONDER));
}

void TunnelSessionClientBase::OnSessionDestroy(Session* session) {
  LOG(LS_INFO) << "TunnelSessionClientBase::OnSessionDestroy";
  ASSERT(session_manager_->signaling_thread()->IsCurrent());
  if (shutdown_)
    return;
  for (std::vector<TunnelSession*>::iterator it = sessions_.begin();
       it != sessions_.end();
       ++it) {
    if ((*it)->HasSession(session)) {
      VERIFY((*it)->ReleaseSession(false) == session);
      sessions_.erase(it);
      return;
    }
  }
}

rtc::StreamInterface* TunnelSessionClientBase::CreateTunnel(
    const buzz::Jid& to, const std::string& description) {
  // Valid from any thread
  CreateTunnelData data;
  data.jid = to;
  data.description = description;
  data.thread = rtc::Thread::Current();
  data.stream = NULL;
  session_manager_->signaling_thread()->Send(this, MSG_CREATE_TUNNEL, &data);
  return data.stream;
}

rtc::StreamInterface* TunnelSessionClientBase::AcceptTunnel(
    Session* session) {
  ASSERT(session_manager_->signaling_thread()->IsCurrent());
  TunnelSession* tunnel = NULL;
  for (std::vector<TunnelSession*>::iterator it = sessions_.begin();
       it != sessions_.end();
       ++it) {
    if ((*it)->HasSession(session)) {
      tunnel = *it;
      break;
    }
  }
  ASSERT(tunnel != NULL);

  SessionDescription* answer = CreateAnswer(session->remote_description());
  if (answer == NULL)
    return NULL;

  session->Accept(answer);
  return tunnel->GetStream();
}

void TunnelSessionClientBase::DeclineTunnel(Session* session) {
  ASSERT(session_manager_->signaling_thread()->IsCurrent());
  session->Reject(STR_TERMINATE_DECLINE);
}

void TunnelSessionClientBase::OnMessage(rtc::Message* pmsg) {
  if (pmsg->message_id == MSG_CREATE_TUNNEL) {
    ASSERT(session_manager_->signaling_thread()->IsCurrent());
    CreateTunnelData* data = static_cast<CreateTunnelData*>(pmsg->pdata);
    SessionDescription* offer = CreateOffer(data->jid, data->description);
    if (offer == NULL) {
      return;
    }

    Session* session = session_manager_->CreateSession(jid_.Str(), namespace_);
    TunnelSession* tunnel = MakeTunnelSession(session, data->thread,
                                              INITIATOR);
    sessions_.push_back(tunnel);
    session->Initiate(data->jid.Str(), offer);
    data->stream = tunnel->GetStream();
  }
}

TunnelSession* TunnelSessionClientBase::MakeTunnelSession(
    Session* session, rtc::Thread* stream_thread,
    TunnelSessionRole /*role*/) {
  return new TunnelSession(this, session, stream_thread);
}

///////////////////////////////////////////////////////////////////////////////
// TunnelSessionClient
///////////////////////////////////////////////////////////////////////////////

TunnelSessionClient::TunnelSessionClient(const buzz::Jid& jid,
                                         SessionManager* manager,
                                         const std::string &ns)
    : TunnelSessionClientBase(jid, manager, ns) {
}

TunnelSessionClient::TunnelSessionClient(const buzz::Jid& jid,
                                         SessionManager* manager)
    : TunnelSessionClientBase(jid, manager, NS_TUNNEL) {
}

TunnelSessionClient::~TunnelSessionClient() {
}


bool TunnelSessionClient::ParseContent(SignalingProtocol protocol,
                                       const buzz::XmlElement* elem,
                                       ContentDescription** content,
                                       ParseError* error) {
  if (const buzz::XmlElement* type_elem = elem->FirstNamed(QN_TUNNEL_TYPE)) {
    *content = new TunnelContentDescription(type_elem->BodyText());
    return true;
  }
  return false;
}

bool TunnelSessionClient::WriteContent(
    SignalingProtocol protocol,
    const ContentDescription* untyped_content,
    buzz::XmlElement** elem, WriteError* error) {
  const TunnelContentDescription* content =
      static_cast<const TunnelContentDescription*>(untyped_content);

  buzz::XmlElement* root = new buzz::XmlElement(QN_TUNNEL_DESCRIPTION, true);
  buzz::XmlElement* type_elem = new buzz::XmlElement(QN_TUNNEL_TYPE);
  type_elem->SetBodyText(content->description);
  root->AddElement(type_elem);
  *elem = root;
  return true;
}

SessionDescription* NewTunnelSessionDescription(
    const std::string& content_name, ContentDescription* content) {
  SessionDescription* sdesc = new SessionDescription();
  sdesc->AddContent(content_name, NS_TUNNEL, content);
  return sdesc;
}

bool FindTunnelContent(const cricket::SessionDescription* sdesc,
                       std::string* name,
                       const TunnelContentDescription** content) {
  const ContentInfo* cinfo = sdesc->FirstContentByType(NS_TUNNEL);
  if (cinfo == NULL)
    return false;

  *name = cinfo->name;
  *content = static_cast<const TunnelContentDescription*>(
      cinfo->description);
  return true;
}

void TunnelSessionClient::OnIncomingTunnel(const buzz::Jid &jid,
                                           Session *session) {
  std::string content_name;
  const TunnelContentDescription* content = NULL;
  if (!FindTunnelContent(session->remote_description(),
                         &content_name, &content)) {
    session->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS);
    return;
  }

  SignalIncomingTunnel(this, jid, content->description, session);
}

SessionDescription* TunnelSessionClient::CreateOffer(
    const buzz::Jid &jid, const std::string &description) {
  SessionDescription* offer = NewTunnelSessionDescription(
      CN_TUNNEL, new TunnelContentDescription(description));
  rtc::scoped_ptr<TransportDescription> tdesc(
      session_manager_->transport_desc_factory()->CreateOffer(
          TransportOptions(), NULL));
  if (tdesc.get()) {
    offer->AddTransportInfo(TransportInfo(CN_TUNNEL, *tdesc));
  } else {
    delete offer;
    offer = NULL;
  }
  return offer;
}

SessionDescription* TunnelSessionClient::CreateAnswer(
    const SessionDescription* offer) {
  std::string content_name;
  const TunnelContentDescription* offer_tunnel = NULL;
  if (!FindTunnelContent(offer, &content_name, &offer_tunnel))
    return NULL;

  SessionDescription* answer = NewTunnelSessionDescription(
      content_name, new TunnelContentDescription(offer_tunnel->description));
  const TransportInfo* tinfo = offer->GetTransportInfoByName(content_name);
  if (tinfo) {
    const TransportDescription* offer_tdesc = &tinfo->description;
    ASSERT(offer_tdesc != NULL);
    rtc::scoped_ptr<TransportDescription> tdesc(
      session_manager_->transport_desc_factory()->CreateAnswer(
          offer_tdesc, TransportOptions(),  NULL));
    if (tdesc.get()) {
      answer->AddTransportInfo(TransportInfo(content_name, *tdesc));
    } else {
      delete answer;
      answer = NULL;
    }
  }
  return answer;
}
///////////////////////////////////////////////////////////////////////////////
// TunnelSession
///////////////////////////////////////////////////////////////////////////////

//
// Signalling thread methods
//

TunnelSession::TunnelSession(TunnelSessionClientBase* client, Session* session,
                             rtc::Thread* stream_thread)
    : client_(client), session_(session), channel_(NULL) {
  ASSERT(client_ != NULL);
  ASSERT(session_ != NULL);
  session_->SignalState.connect(this, &TunnelSession::OnSessionState);
  channel_ = new PseudoTcpChannel(stream_thread, session_);
  channel_->SignalChannelClosed.connect(this, &TunnelSession::OnChannelClosed);
}

TunnelSession::~TunnelSession() {
  ASSERT(client_ != NULL);
  ASSERT(session_ == NULL);
  ASSERT(channel_ == NULL);
}

rtc::StreamInterface* TunnelSession::GetStream() {
  ASSERT(channel_ != NULL);
  return channel_->GetStream();
}

bool TunnelSession::HasSession(Session* session) {
  ASSERT(NULL != session_);
  return (session_ == session);
}

Session* TunnelSession::ReleaseSession(bool channel_exists) {
  ASSERT(NULL != session_);
  ASSERT(NULL != channel_);
  Session* session = session_;
  session_->SignalState.disconnect(this);
  session_ = NULL;
  if (channel_exists)
    channel_->SignalChannelClosed.disconnect(this);
  channel_ = NULL;
  delete this;
  return session;
}

void TunnelSession::OnSessionState(BaseSession* session,
                                   BaseSession::State state) {
  LOG(LS_INFO) << "TunnelSession::OnSessionState("
               << rtc::nonnull(
                    rtc::FindLabel(state, SESSION_STATES), "Unknown")
               << ")";
  ASSERT(session == session_);

  switch (state) {
  case Session::STATE_RECEIVEDINITIATE:
    OnInitiate();
    break;
  case Session::STATE_SENTACCEPT:
  case Session::STATE_RECEIVEDACCEPT:
    OnAccept();
    break;
  case Session::STATE_SENTTERMINATE:
  case Session::STATE_RECEIVEDTERMINATE:
    OnTerminate();
    break;
  case Session::STATE_DEINIT:
    // ReleaseSession should have been called before this.
    ASSERT(false);
    break;
  default:
    break;
  }
}

void TunnelSession::OnInitiate() {
  ASSERT(client_ != NULL);
  ASSERT(session_ != NULL);
  client_->OnIncomingTunnel(buzz::Jid(session_->remote_name()), session_);
}

void TunnelSession::OnAccept() {
  ASSERT(channel_ != NULL);
  const ContentInfo* content =
      session_->remote_description()->FirstContentByType(NS_TUNNEL);
  ASSERT(content != NULL);
  VERIFY(channel_->Connect(
      content->name, "tcp", ICE_CANDIDATE_COMPONENT_DEFAULT));
}

void TunnelSession::OnTerminate() {
  ASSERT(channel_ != NULL);
  channel_->OnSessionTerminate(session_);
}

void TunnelSession::OnChannelClosed(PseudoTcpChannel* channel) {
  ASSERT(channel_ == channel);
  ASSERT(session_ != NULL);
  session_->Terminate();
}

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

} // namespace cricket
