/*
 * 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_GIPSMEDIAENGINE_H_
#define TALK_SESSION_PHONE_GIPSMEDIAENGINE_H_

#include <map>
#include <set>
#include <string>
#include <vector>

#include "talk/base/buffer.h"
#include "talk/base/byteorder.h"
#include "talk/base/logging.h"
#include "talk/base/scoped_ptr.h"
#include "talk/base/stream.h"
#include "talk/session/phone/channel.h"
#include "talk/session/phone/mediaengine.h"
#include "talk/session/phone/gips.h"
#include "talk/session/phone/rtputils.h"

namespace cricket {

// GipsSoundclipStream is an adapter object that allows a memory stream to be
// passed into GIPS, and support looping.
class GipsSoundclipStream : public InStream {
 public:
  GipsSoundclipStream(const char* buf, size_t len)
      : mem_(buf, len), loop_(true) {
  }
  void set_loop(bool loop) { loop_ = loop; }
  virtual int Read(void* buf, int len);
  virtual int Rewind();

 private:
  talk_base::MemoryStream mem_;
  bool loop_;
};

// GipsMonitorStream is used to monitor a stream coming from GIPS.
// For now we just dump the data.
class GipsMonitorStream : public OutStream {
  virtual bool Write(const void *buf, int len) {
    return true;
  }
};

class GipsSoundclipMedia;
class GipsVoiceMediaChannel;

// GipsVoiceEngine is a class to be used with CompositeMediaEngine.
// It uses the GIPS VoiceEngine library for audio handling.
class GipsVoiceEngine
    : public GIPSVoiceEngineObserver,
      public GIPSTraceCallback {
 public:
  GipsVoiceEngine();  // NOLINT
  // Dependency injection for testing.
  GipsVoiceEngine(GipsWrapper* gips,
                  GipsWrapper* gips_sc,
                  GipsTraceWrapper* tracing);
  ~GipsVoiceEngine();
  bool Init();
  void Terminate();

  int GetCapabilities();
  VoiceMediaChannel* CreateChannel();

  SoundclipMedia *CreateSoundclip();

  bool SetOptions(int options);
  bool SetDevices(const Device* in_device, const Device* out_device);
  bool GetOutputVolume(int* level);
  bool SetOutputVolume(int level);
  int GetInputLevel();
  bool SetLocalMonitor(bool enable);

  const std::vector<AudioCodec>& codecs();
  bool FindCodec(const AudioCodec& codec);
  bool FindGIPSCodec(const AudioCodec& codec, GIPS_CodecInst* gcodec);

  void SetLogging(int min_sev, const char* filter);

  // For tracking GIPS channels. Needed because we have to pause them
  // all when switching devices.
  // May only be called by GipsVoiceMediaChannel.
  void RegisterChannel(GipsVoiceMediaChannel *channel);
  void UnregisterChannel(GipsVoiceMediaChannel *channel);
  // May only be called by GipsSoundclipMedia.
  void RegisterSoundclip(GipsSoundclipMedia *channel);
  void UnregisterSoundclip(GipsSoundclipMedia *channel);

  // Called by GipsVoiceMediaChannel to set a gain offset from
  // the default AGC target level.
  bool AdjustAgcLevel(int delta);

  // Called by GipsVoiceMediaChannel to configure echo cancellation
  // and noise suppression modes.
  bool SetConferenceMode(bool enable);

  GipsWrapper* gips() { return gips_.get(); }
  GipsWrapper* gips_sc() { return gips_sc_.get(); }
  int GetLastGipsError();

 private:
  typedef std::vector<GipsSoundclipMedia *> SoundclipList;
  typedef std::vector<GipsVoiceMediaChannel *> ChannelList;

  struct CodecPref {
    const char* name;
    int clockrate;
  };

  void Construct();
  bool InitInternal();
  void ApplyLogging(const std::string& log_filter);
  virtual void Print(const GIPS::TraceLevel level,
                     const char* traceString, const int length);
  virtual void CallbackOnError(const int channel, const int errCode);
  static int GetCodecPreference(const char *name, int clockrate);
  // Given the device type, name, and id, find GIPS's device id. Return true and
  // set the output parameter gips_id if successful.
  bool FindGipsAudioDeviceId(
      bool is_input, const std::string& dev_name, int dev_id, int* gips_id);
  bool FindChannelAndSsrc(int channel_num,
                          GipsVoiceMediaChannel** channel,
                          uint32* ssrc) const;
  bool ChangeLocalMonitor(bool enable);
  bool PauseLocalMonitor();
  bool ResumeLocalMonitor();

  static const int kDefaultLogSeverity = talk_base::LS_WARNING;
  static const CodecPref kCodecPrefs[];

  // The primary instance of GIPS VoiceEngine.
  talk_base::scoped_ptr<GipsWrapper> gips_;
  // A secondary instance, for playing out soundclips (on the 'ring' device).
  talk_base::scoped_ptr<GipsWrapper> gips_sc_;
  talk_base::scoped_ptr<GipsTraceWrapper> tracing_;
  int log_level_;
  std::string log_filter_;
  bool is_dumping_aec_;
  std::vector<AudioCodec> codecs_;
  bool desired_local_monitor_enable_;
  talk_base::scoped_ptr<GipsMonitorStream> monitor_;
  SoundclipList soundclips_;
  ChannelList channels_;
  // channels_ can be read from GIPS callback thread. We need a lock on that
  // callback as well as the RegisterChannel/UnregisterChannel.
  talk_base::CriticalSection channels_cs_;
  GIPS_AGC_config default_agc_config_;
  bool initialized_;

  talk_base::CriticalSection signal_media_critical_;
};

// GipsMediaChannel is a class that implements the common GIPS channel
// functionality.
template <class T, class E>
class GipsMediaChannel : public T, public GIPS_transport {
 public:
  GipsMediaChannel(E *engine, int channel)
      : engine_(engine), gips_channel_(channel), sequence_number_(-1) {}
  E *engine() { return engine_; }
  int gips_channel() const { return gips_channel_; }
  bool valid() const { return gips_channel_ != -1; }

 protected:
  // implements GIPS_transport interface
  virtual int SendPacket(int channel, const void *data, int len) {
    if (!T::network_interface_) {
      return -1;
    }

    // We need to store the sequence number to be able to pick up
    // the same sequence when the device is restarted.
    // TODO(oja): Remove when GIPS has fixed the problem.
    int seq_num;
    if (!GetRtpSeqNum(data, len, &seq_num)) {
      return -1;
    }
    if (sequence_number() == -1) {
      LOG(LS_INFO) << "GipsVoiceMediaChannel sends first packet seqnum="
                   << seq_num;
    }
    sequence_number_ = seq_num;

    talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
    return T::network_interface_->SendPacket(&packet) ? len : -1;
  }
  virtual int SendRTCPPacket(int channel, const void *data, int len) {
    if (!T::network_interface_) {
      return -1;
    }

    talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
    return T::network_interface_->SendRtcp(&packet) ? len : -1;
  }
  int sequence_number() const {
    return sequence_number_;
  }

 private:
  E *engine_;
  int gips_channel_;
  int sequence_number_;
};

// GipsVoiceMediaChannel is an implementation of VoiceMediaChannel that uses
// GIPS Voice Engine.
class GipsVoiceMediaChannel
    : public GipsMediaChannel<VoiceMediaChannel, GipsVoiceEngine> {
 public:
  explicit GipsVoiceMediaChannel(GipsVoiceEngine *engine);
  virtual ~GipsVoiceMediaChannel();
  virtual bool SetOptions(int options);
  virtual bool SetRecvCodecs(const std::vector<AudioCodec> &codecs);
  virtual bool SetSendCodecs(const std::vector<AudioCodec> &codecs);
  virtual bool SetRecvRtpHeaderExtensions(
      const std::vector<RtpHeaderExtension> &extensions);
  virtual bool SetSendRtpHeaderExtensions(
      const std::vector<RtpHeaderExtension> &extensions);
  virtual bool SetPlayout(bool playout);
  bool PausePlayout();
  bool ResumePlayout();
  virtual bool SetSend(SendFlags send);
  bool PauseSend();
  bool ResumeSend();

  virtual bool AddStream(uint32 ssrc);
  virtual bool RemoveStream(uint32 ssrc);
  virtual bool GetActiveStreams(AudioInfo::StreamList* actives);
  virtual int GetOutputLevel();
  virtual bool SetOutputScaling(uint32 ssrc, double left, double right);
  virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right);

  virtual bool SetRingbackTone(const char *buf, int len);
  virtual bool PlayRingbackTone(uint32 ssrc, bool play, bool loop);
  virtual bool PressDTMF(int event, bool playout);

  virtual void OnPacketReceived(talk_base::Buffer* packet);
  virtual void OnRtcpReceived(talk_base::Buffer* packet);
  virtual void SetSendSsrc(uint32 id);
  virtual bool SetRtcpCName(const std::string& cname);
  virtual bool Mute(bool mute);
  virtual bool SetSendBandwidth(bool autobw, int bps) { return false; }
  virtual bool GetStats(VoiceMediaInfo* info);
  // Gets last reported error from GIPS voice engine.  This should be only
  // called in response a failure.
  virtual void GetLastMediaError(uint32* ssrc,
                                 VoiceMediaChannel::Error* error);
  bool FindSsrc(int gips_channel, uint32* ssrc);
  void OnError(uint32 ssrc, int error);

 protected:
  int GetLastGipsError() { return engine()->GetLastGipsError(); }
  int GetChannel(uint32 ssrc);
  int GetOutputLevel(int channel);
  bool GetRedSendCodec(const AudioCodec& red_codec,
                       const std::vector<AudioCodec>& all_codecs,
                       GIPS_CodecInst* send_codec);
  bool EnableRtcp(int channel);
  bool SetPlayout(int channel, bool playout);
  static uint32 ParseSsrc(const void* data, size_t len, bool rtcp);
  static Error GipsErrorToChannelError(int err_code);

 private:
  // Tandberg-bridged conferences require a -10dB gain adjustment,
  // which is actually +10 in GIPS_AGC_config.targetLeveldBOv
  static const int kTandbergDbAdjustment = 10;

  bool ChangePlayout(bool playout);
  bool ChangeSend(SendFlags send);

  typedef std::map<uint32, int> ChannelMap;
  talk_base::scoped_ptr<GipsSoundclipStream> ringback_tone_;
  std::set<int> ringback_channels_;  // channels playing ringback
  int channel_options_;
  bool agc_adjusted_;
  bool dtmf_allowed_;
  bool desired_playout_;
  bool playout_;
  SendFlags desired_send_;
  SendFlags send_;
  ChannelMap mux_channels_;  // for multiple sources
  // mux_channels_ can be read from GIPS callback thread.  Accesses off the
  // GIPS thread must be synchronized with edits on the worker thread.  Reads
  // on the worker thread are ok.
  mutable talk_base::CriticalSection mux_channels_cs_;
};

}  // namespace cricket

#endif  // TALK_SESSION_PHONE_GIPSMEDIAENGINE_H_
