/*
 * 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.
 */

#ifndef TALK_SESSION_PHONE_MEDIASESSIONCLIENT_H_
#define TALK_SESSION_PHONE_MEDIASESSIONCLIENT_H_

#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include "talk/session/phone/call.h"
#include "talk/session/phone/channelmanager.h"
#include "talk/session/phone/cryptoparams.h"
#include "talk/base/sigslot.h"
#include "talk/base/sigslotrepeater.h"
#include "talk/base/messagequeue.h"
#include "talk/base/thread.h"
#include "talk/p2p/base/sessionmanager.h"
#include "talk/p2p/base/session.h"
#include "talk/p2p/base/sessionclient.h"
#include "talk/p2p/base/sessiondescription.h"

namespace cricket {

class Call;
class SessionDescription;
typedef std::vector<AudioCodec> AudioCodecs;
typedef std::vector<VideoCodec> VideoCodecs;

// SEC_ENABLED and SEC_REQUIRED should only be used if the session
// was negotiated over TLS, to protect the inline crypto material
// exchange.
// SEC_DISABLED: No crypto in outgoing offer and answer. Fail any
//               offer with crypto required.
// SEC_ENABLED: Crypto in outgoing offer and answer. Fail any offer
//              with unsupported required crypto. Crypto set but not
//              required in outgoing offer.
// SEC_REQUIRED: Crypto in outgoing offer and answer with
//               required='true'. Fail any offer with no or
//               unsupported crypto (implicit crypto required='true'
//               in the offer.)
enum SecureMediaPolicy {SEC_DISABLED, SEC_ENABLED, SEC_REQUIRED};

const int kAutoBandwidth = -1;

struct CallOptions {
  CallOptions() :
      is_video(false),
      is_muc(false),
      video_bandwidth(kAutoBandwidth) {
  }

  bool is_video;
  bool is_muc;
  // bps. -1 == auto.
  int video_bandwidth;
};

class MediaSessionClient: public SessionClient, public sigslot::has_slots<> {
 public:

  MediaSessionClient(const buzz::Jid& jid, SessionManager *manager);
  // Alternative constructor, allowing injection of media_engine
  // and device_manager.
  MediaSessionClient(const buzz::Jid& jid, SessionManager *manager,
      MediaEngine* media_engine, DeviceManager* device_manager);
  ~MediaSessionClient();

  const buzz::Jid &jid() const { return jid_; }
  SessionManager* session_manager() const { return session_manager_; }
  ChannelManager* channel_manager() const { return channel_manager_; }

  int GetCapabilities() { return channel_manager_->GetCapabilities(); }

  Call *CreateCall();
  void DestroyCall(Call *call);

  Call *GetFocus();
  void SetFocus(Call *call);

  void JoinCalls(Call *call_to_join, Call *call);

  bool GetAudioInputDevices(std::vector<std::string>* names) {
    return channel_manager_->GetAudioInputDevices(names);
  }
  bool GetAudioOutputDevices(std::vector<std::string>* names) {
    return channel_manager_->GetAudioOutputDevices(names);
  }
  bool GetVideoCaptureDevices(std::vector<std::string>* names) {
    return channel_manager_->GetVideoCaptureDevices(names);
  }

  bool SetAudioOptions(const std::string& in_name, const std::string& out_name,
                       int opts) {
    return channel_manager_->SetAudioOptions(in_name, out_name, opts);
  }
  bool SetOutputVolume(int level) {
    return channel_manager_->SetOutputVolume(level);
  }
  bool SetVideoOptions(const std::string& cam_device) {
    return channel_manager_->SetVideoOptions(cam_device);
  }

  sigslot::signal2<Call *, Call *> SignalFocus;
  sigslot::signal1<Call *> SignalCallCreate;
  sigslot::signal1<Call *> SignalCallDestroy;
  sigslot::repeater0<> SignalDevicesChange;

  SessionDescription* CreateOffer(const CallOptions& options);
  SessionDescription* CreateAnswer(const SessionDescription* offer,
                                   const CallOptions& options);

  SecureMediaPolicy secure() const { return secure_; }
  void set_secure(SecureMediaPolicy s) { secure_ = s; }

 private:
  void Construct();
  void OnSessionCreate(Session *session, bool received_initiate);
  void OnSessionState(BaseSession *session, BaseSession::State state);
  void OnSessionDestroy(Session *session);
  virtual bool ParseContent(SignalingProtocol protocol,
                            const buzz::XmlElement* elem,
                            const ContentDescription** content,
                            ParseError* error);
  virtual bool WriteContent(SignalingProtocol protocol,
                            const ContentDescription* content,
                            buzz::XmlElement** elem,
                            WriteError* error);
  Session *CreateSession(Call *call);

  buzz::Jid jid_;
  SessionManager* session_manager_;
  Call *focus_call_;
  ChannelManager *channel_manager_;
  std::map<uint32, Call *> calls_;
  std::map<std::string, Call *> session_map_;
  SecureMediaPolicy secure_;
  friend class Call;
};

enum MediaType {
  MEDIA_TYPE_AUDIO,
  MEDIA_TYPE_VIDEO
};

class MediaContentDescription : public ContentDescription {
 public:
  MediaContentDescription()
      : ssrc_(0),
        ssrc_set_(false),
        rtcp_mux_(false), 
        rtp_headers_disabled_(false),
        crypto_required_(false),
        bandwidth_(kAutoBandwidth) {
  }

  virtual MediaType type() const = 0;

  uint32 ssrc() const { return ssrc_; }
  bool ssrc_set() const { return ssrc_set_; }
  void set_ssrc(uint32 ssrc) {
    ssrc_ = ssrc;
    ssrc_set_ = true;
  }

  bool rtcp_mux() const { return rtcp_mux_; }
  void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; }

  bool rtp_headers_disabled() const {
    return rtp_headers_disabled_;
  }
  void set_rtp_headers_disabled(bool disable) {
    rtp_headers_disabled_ = disable;
  }

  const std::vector<CryptoParams>& cryptos() const { return cryptos_; }
  void AddCrypto(const CryptoParams& params) {
    cryptos_.push_back(params);
  }
  bool crypto_required() const { return crypto_required_; }
  void set_crypto_required(bool crypto) {
    crypto_required_ = crypto;
  }

  int bandwidth() const { return bandwidth_; }
  void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; }

 protected:
  uint32 ssrc_;
  bool ssrc_set_;
  bool rtcp_mux_;
  bool rtp_headers_disabled_;
  std::vector<CryptoParams> cryptos_;
  bool crypto_required_;
  int bandwidth_;
};

template <class C>
class MediaContentDescriptionImpl : public MediaContentDescription {
 public:
  struct PreferenceSort {
    bool operator()(C a, C b) { return a.preference > b.preference; }
  };

  const std::vector<C>& codecs() const { return codecs_; }
  void AddCodec(const C& codec) {
    codecs_.push_back(codec);
  }
  void SortCodecs() {
    std::sort(codecs_.begin(), codecs_.end(), PreferenceSort());
  }

 private:
  std::vector<C> codecs_;
};

class AudioContentDescription : public MediaContentDescriptionImpl<AudioCodec> {
 public:
  AudioContentDescription() :
      conference_mode_(false) {}

  virtual MediaType type() const { return MEDIA_TYPE_AUDIO; }

  bool conference_mode() const { return conference_mode_; }
  void set_conference_mode(bool enable) {
    conference_mode_ = enable;
  }

  const std::string &lang() const { return lang_; }
  void set_lang(const std::string &lang) { lang_ = lang; }


 private:
  bool conference_mode_;
  std::string lang_;
};

class VideoContentDescription : public MediaContentDescriptionImpl<VideoCodec> {
 public:
  virtual MediaType type() const { return MEDIA_TYPE_VIDEO; }
};

// Convenience functions.
const ContentInfo* GetFirstAudioContent(const SessionDescription* sdesc);
const ContentInfo* GetFirstVideoContent(const SessionDescription* sdesc);


}  // namespace cricket

#endif  // TALK_SESSION_PHONE_MEDIASESSIONCLIENT_H_
