/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "video_engine/vie_impl.h"

#if (defined(WIN32_) || defined(WIN64_))
#include <Windows.h>  // For LoadLibrary.
#include <tchar.h>    // For T_.
#endif

#include "system_wrappers/interface/trace.h"

#ifdef WEBRTC_ANDROID
#include "modules/video_capture/main/interface/video_capture_factory.h"
#include "modules/video_render/main/interface/video_render.h"
#endif

// Global counter to get an id for each new ViE instance.
static WebRtc_Word32 g_vie_active_instance_counter = 0;

namespace webrtc {

// extern "C" ensures that GetProcAddress() can find the function address.
extern "C" {
  VideoEngine* GetVideoEngine() {
    VideoEngineImpl* self = new VideoEngineImpl();
    if (!self) {
      return NULL;
    }
    g_vie_active_instance_counter++;
    VideoEngine* vie = reinterpret_cast<VideoEngine*>(self);
    return vie;
  }
}

VideoEngine* VideoEngine::Create() {
#if (defined(WIN32_) || defined(WIN64_))
  // Load a debug dll, if there is one.
  HMODULE hmod_ = LoadLibrary(TEXT("VideoEngineTestingDLL.dll"));
  if (hmod_) {
    typedef VideoEngine* (*PFNGetVideoEngineLib)(void);
    PFNGetVideoEngineLib pfn =
      (PFNGetVideoEngineLib)GetProcAddress(hmod_, "GetVideoEngine");
    if (pfn) {
      VideoEngine* self = pfn();
      return self;
    } else {
      assert(!"Failed to open test dll VideoEngineTestingDLL.dll");
      return NULL;
    }
  }
#endif

  return GetVideoEngine();
}

bool VideoEngine::Delete(VideoEngine*& video_engine) {
  if (!video_engine) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "VideoEngine::Delete - No argument");
    return false;
  }
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, g_vie_active_instance_counter,
               "VideoEngine::Delete(vie = 0x%p)", video_engine);
  VideoEngineImpl* vie_impl = reinterpret_cast<VideoEngineImpl*>(video_engine);

  // Check all reference counters.
  ViEBaseImpl* vie_base = vie_impl;
  if (vie_base->GetCount() > 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "ViEBase ref count: %d", vie_base->GetCount());
    return false;
  }
#ifdef WEBRTC_VIDEO_ENGINE_CAPTURE_API
  ViECaptureImpl* vie_capture = vie_impl;
  if (vie_capture->GetCount() > 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "ViECapture ref count: %d", vie_capture->GetCount());
    return false;
  }
#endif
#ifdef WEBRTC_VIDEO_ENGINE_CODEC_API
  ViECodecImpl* vie_codec = vie_impl;
  if (vie_codec->GetCount() > 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "ViECodec ref count: %d", vie_codec->GetCount());
    return false;
  }
#endif
#ifdef WEBRTC_VIDEO_ENGINE_ENCRYPTION_API
  ViEEncryptionImpl* vie_encryption = vie_impl;
  if (vie_encryption->GetCount() > 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "ViEEncryption ref count: %d", vie_encryption->GetCount());
    return false;
  }
#endif
#ifdef WEBRTC_VIDEO_ENGINE_EXTERNAL_CODEC_API
  ViEExternalCodecImpl* vie_external_codec = vie_impl;
  if (vie_external_codec->GetCount() > 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "ViEEncryption ref count: %d", vie_encryption->GetCount());
    return false;
  }
#endif
#ifdef WEBRTC_VIDEO_ENGINE_FILE_API
  ViEFileImpl* vie_file = vie_impl;
  if (vie_file->GetCount() > 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "ViEFile ref count: %d", vie_file->GetCount());
    return false;
  }
#endif
#ifdef WEBRTC_VIDEO_ENGINE_IMAGE_PROCESS_API
  ViEImageProcessImpl* vie_image_process = vie_impl;
  if (vie_image_process->GetCount() > 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "ViEImageProcess ref count: %d",
                 vie_image_process->GetCount());
    return false;
  }
#endif
#ifdef WEBRTC_VIDEO_ENGINE_NETWORK_API
  ViENetworkImpl* vie_network = vie_impl;
  if (vie_network->GetCount() > 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "ViENetwork ref count: %d", vie_network->GetCount());
    return false;
  }
#endif
#ifdef WEBRTC_VIDEO_ENGINE_RENDER_API
  ViERenderImpl* vie_render = vie_impl;
  if (vie_render->GetCount() > 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "ViERender ref count: %d", vie_render->GetCount());
    return false;
  }
#endif
#ifdef WEBRTC_VIDEO_ENGINE_RTP_RTCP_API
  ViERTP_RTCPImpl* vie_rtp_rtcp = vie_impl;
  if (vie_rtp_rtcp->GetCount() > 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "ViERTP_RTCP ref count: %d", vie_rtp_rtcp->GetCount());
    return false;
  }
#endif

  delete vie_impl;
  vie_impl = NULL;
  video_engine = NULL;

  // Decrease the number of instances.
  g_vie_active_instance_counter--;

  WEBRTC_TRACE(kTraceInfo, kTraceVideo, g_vie_active_instance_counter,
               "%s: instance deleted. Remaining instances: %d", __FUNCTION__,
               g_vie_active_instance_counter);
  return true;
}

int VideoEngine::SetTraceFile(const char* file_nameUTF8,
                              const bool add_file_counter) {
  if (!file_nameUTF8) {
    return -1;
  }
  if (Trace::SetTraceFile(file_nameUTF8, add_file_counter) == -1) {
    return -1;
  }
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, g_vie_active_instance_counter,
               "SetTraceFileName(file_nameUTF8 = %s, add_file_counter = %d",
               file_nameUTF8, add_file_counter);
  return 0;
}

int VideoEngine::SetTraceFilter(const unsigned int filter) {
  WebRtc_UWord32 old_filter = 0;
  Trace::LevelFilter(old_filter);

  if (filter == kTraceNone && old_filter != kTraceNone) {
    // Do the logging before turning it off.
    WEBRTC_TRACE(kTraceApiCall, kTraceVideo, g_vie_active_instance_counter,
                 "SetTraceFilter(filter = 0x%x)", filter);
  }

  WebRtc_Word32 error = Trace::SetLevelFilter(filter);
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, g_vie_active_instance_counter,
               "SetTraceFilter(filter = 0x%x)", filter);
  if (error != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "SetTraceFilter error: %d", error);
    return -1;
  }
  return 0;
}

int VideoEngine::SetTraceCallback(TraceCallback* callback) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, g_vie_active_instance_counter,
               "SetTraceCallback(TraceCallback = 0x%p)", callback);
  return Trace::SetTraceCallback(callback);
}

int VideoEngine::SetAndroidObjects(void* javaVM, void* javaContext) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, g_vie_active_instance_counter,
               "SetAndroidObjects()");

#ifdef WEBRTC_ANDROID
  if (VideoCaptureFactory::SetAndroidObjects(javaVM, javaContext) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "Could not set capture module Android objects");
    return -1;
  }
  if (VideoRender::SetAndroidObjects(javaVM) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                 "Could not set render module Android objects");
    return -1;
  }
  return 0;
#else
  WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
               "WEBRTC_ANDROID not defined for VideoEngine::SetAndroidObjects");
  return -1;
#endif
}

}  // namespace webrtc
