// Copyright 2007 Google Inc. All Rights Reserved
// Author: juberti@google.com (Justin Uberti)

#ifndef TALK_SESSION_PHONE_GIPS_H_
#define TALK_SESSION_PHONE_GIPS_H_

#include "talk/base/common.h"
#include "gips/Interface/GIPSVEBase.h"
#include "gips/Interface/GIPSVECodec.h"
#include "gips/Interface/GIPSVEDTMF.h"
#include "gips/Interface/GIPSVEErrors.h"
#include "gips/Interface/GIPSVEFile.h"
#include "gips/Interface/GIPSVEHardware.h"
#include "gips/Interface/GIPSVENetwork.h"
#include "gips/Interface/GIPSVENetEqStats.h"
#include "gips/Interface/GIPSVERTP_RTCP.h"
#include "gips/Interface/GIPSVEVideoSync.h"
#include "gips/Interface/GIPSVEVolumeControl.h"
#include "gips/Interface/GIPSVEVQE.h"

// Tracing helpers, for easy logging when GIPS calls fail.
// Example: "LOG_GIPSERR1(StartSend, channel);" produces the trace
//          "GIPSVE_StartSend(1) failed, err=XXXX"
// The method GetLastGipsError must be defined in the calling scope.
#define LOG_GIPSERR0(func) \
    LOG_GIPSERR0_EX(func, GetLastGipsError())
#define LOG_GIPSERR1(func, a1) \
    LOG_GIPSERR1_EX(func, a1, GetLastGipsError())
#define LOG_GIPSERR2(func, a1, a2) \
    LOG_GIPSERR2_EX(func, a1, a2, GetLastGipsError())
#define LOG_GIPSERR3(func, a1, a2, a3) \
    LOG_GIPSERR3_EX(func, a1, a2, a3, GetLastGipsError())
#define LOG_GIPSERR0_EX(func, err) LOG(LS_WARNING) \
    << "GIPSVE_" << #func << "() failed, err=" << err
#define LOG_GIPSERR1_EX(func, a1, err) LOG(LS_WARNING) \
    << "GIPSVE_" << #func << "(" << a1 << ") failed, err=" << err
#define LOG_GIPSERR2_EX(func, a1, a2, err) LOG(LS_WARNING) \
    << "GIPSVE_" << #func << "(" << a1 << ", " << a2 << ") failed, err=" \
    << err
#define LOG_GIPSERR3_EX(func, a1, a2, a3, err) LOG(LS_WARNING) \
    << "GIPSVE_" << #func << "(" << a1 << ", " << a2 << ", " << a3 \
    << ") failed, err=" << err

// automatically handles lifetime of GIPS VoiceEngine
class scoped_gips_engine {
 public:
  explicit scoped_gips_engine(GIPSVoiceEngine* e) : ptr(e) {}
  // VERIFY, to ensure that there are no leaks at shutdown
  ~scoped_gips_engine() { if (ptr) VERIFY(GIPSVoiceEngine::Delete(ptr)); }
  GIPSVoiceEngine* get() const { return ptr; }
 private:
  GIPSVoiceEngine* ptr;
};

// scoped_ptr class to handle obtaining and releasing GIPS interface pointers
template<class T> class scoped_gips_ptr {
 public:
  explicit scoped_gips_ptr(const scoped_gips_engine& e)
       : ptr(T::GIPSVE_GetInterface(e.get())) {}
  explicit scoped_gips_ptr(T* p) : ptr(p) {}
  ~scoped_gips_ptr() { if (ptr) ptr->GIPSVE_Release(); }
  T* operator->() const { return ptr; }
  T* get() const { return ptr; }
 private:
  T* ptr;
};

// allows one to do gips_cast<GIPSVEXXXX>(engine)->foo()
#define gips_cast scoped_gips_ptr

// Utility class for aggregating the various GIPS interface.
// Fake implementations can also be injected for testing.
class GipsWrapper {
 public:
  GipsWrapper()
      : engine_(GIPSVoiceEngine::Create()),
        base_(engine_),
        codec_(engine_),
        dtmf_(engine_),
        file_(engine_),
        hw_(engine_),
        neteq_(engine_),
        network_(engine_),
        rtp_(engine_),
        sync_(engine_),
        volume_(engine_),
        vqe_(engine_) {
  }
  GipsWrapper(GIPSVEBase* base, GIPSVECodec* codec, GIPSVEDTMF* dtmf,
              GIPSVEFile* file, GIPSVEHardware* hw, GIPSVENetEqStats* neteq,
              GIPSVENetwork* network, GIPSVERTP_RTCP* rtp,
              GIPSVEVideoSync* sync, GIPSVEVolumeControl* volume,
              GIPSVEVQE* vqe)
      : engine_(NULL),
        base_(base),
        codec_(codec),
        dtmf_(dtmf),
        file_(file),
        hw_(hw),
        neteq_(neteq),
        network_(network),
        rtp_(rtp),
        sync_(sync),
        volume_(volume),
        vqe_(vqe) {
  }
  virtual ~GipsWrapper() {}
  GIPSVEBase* base() { return base_.get(); }
  GIPSVECodec* codec() { return codec_.get(); }
  GIPSVEDTMF* dtmf() { return dtmf_.get(); }
  GIPSVEFile* file() { return file_.get(); }
  GIPSVEHardware* hw() { return hw_.get(); }
  GIPSVENetEqStats* neteq() { return neteq_.get(); }
  GIPSVENetwork* network() { return network_.get(); }
  GIPSVERTP_RTCP* rtp() { return rtp_.get(); }
  GIPSVEVideoSync* sync() { return sync_.get(); }
  GIPSVEVolumeControl* volume() { return volume_.get(); }
  GIPSVEVQE* vqe() { return vqe_.get(); }
  int error() { return base_->GIPSVE_LastError(); }

 private:
  scoped_gips_engine engine_;
  scoped_gips_ptr<GIPSVEBase> base_;
  scoped_gips_ptr<GIPSVECodec> codec_;
  scoped_gips_ptr<GIPSVEDTMF> dtmf_;
  scoped_gips_ptr<GIPSVEFile> file_;
  scoped_gips_ptr<GIPSVEHardware> hw_;
  scoped_gips_ptr<GIPSVENetEqStats> neteq_;
  scoped_gips_ptr<GIPSVENetwork> network_;
  scoped_gips_ptr<GIPSVERTP_RTCP> rtp_;
  scoped_gips_ptr<GIPSVEVideoSync> sync_;
  scoped_gips_ptr<GIPSVEVolumeControl> volume_;
  scoped_gips_ptr<GIPSVEVQE> vqe_;
};

// Adds indirection to static GIPS functions, allowing them to be mocked.
class GipsTraceWrapper {
 public:
  virtual ~GipsTraceWrapper() {}

  virtual int SetTraceFilter(const unsigned int filter) {
    return GIPSVoiceEngine::SetTraceFilter(filter);
  }
  virtual int SetTraceFile(const char* fileNameUTF8) {
    return GIPSVoiceEngine::SetTraceFile(fileNameUTF8);
  }
  virtual int SetEncryptedTraceFile(const char* fileNameUTF8) {
    return GIPSVoiceEngine::SetEncryptedTraceFile(fileNameUTF8);
  }
  virtual int SetTraceCallback(GIPSTraceCallback* callback) {
    return GIPSVoiceEngine::SetTraceCallback(callback);
  }
};

#endif  // TALK_SESSION_PHONE_GIPS_H_
