/*
 * libjingle
 * Copyright 2004 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 "talk/session/phone/devicemanager.h"

#include "talk/base/logging.h"
#include "talk/base/stringutils.h"
#include "talk/base/thread.h"
#include "talk/session/phone/mediacommon.h"

namespace cricket {
// Initialize to empty string.
const char DeviceManagerInterface::kDefaultDeviceName[] = "";

DeviceManager::DeviceManager()
    : initialized_(false) {
}

DeviceManager::~DeviceManager() {
  if (initialized()) {
    Terminate();
  }
}

bool DeviceManager::Init() {
  if (!initialized()) {
    if (!watcher()->Start()) {
      return false;
    }
    set_initialized(true);
  }
  return true;
}

void DeviceManager::Terminate() {
  if (initialized()) {
    watcher()->Stop();
    set_initialized(false);
  }
}

int DeviceManager::GetCapabilities() {
  std::vector<Device> devices;
  int caps = VIDEO_RECV;
  if (GetAudioInputDevices(&devices) && !devices.empty()) {
    caps |= AUDIO_SEND;
  }
  if (GetAudioOutputDevices(&devices) && !devices.empty()) {
    caps |= AUDIO_RECV;
  }
  if (GetVideoCaptureDevices(&devices) && !devices.empty()) {
    caps |= VIDEO_SEND;
  }
  return caps;
}

bool DeviceManager::GetAudioInputDevices(std::vector<Device>* devices) {
  return GetAudioDevices(true, devices);
}

bool DeviceManager::GetAudioOutputDevices(std::vector<Device>* devices) {
  return GetAudioDevices(false, devices);
}

bool DeviceManager::GetAudioInputDevice(const std::string& name, Device* out) {
  return GetAudioDevice(true, name, out);
}

bool DeviceManager::GetAudioOutputDevice(const std::string& name, Device* out) {
  return GetAudioDevice(false, name, out);
}

bool DeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
  devices->clear();
#if defined(ANDROID) || defined(IOS)
  // TODO: Incomplete. Use ANDROID implementation for IOS
  // to quiet compiler.
  // On Android, we treat the camera(s) as a single device. Even if there are
  // multiple cameras, that's abstracted away at a higher level.
  Device dev("camera", "1");    // name and ID
  devices->push_back(dev);
#else
  return false;
#endif
}

bool DeviceManager::GetVideoCaptureDevice(const std::string& name,
                                          Device* out) {
  // If the name is empty, return the default device.
  if (name.empty() || name == kDefaultDeviceName) {
    return GetDefaultVideoCaptureDevice(out);
  }

  std::vector<Device> devices;
  if (!GetVideoCaptureDevices(&devices)) {
    return false;
  }

  for (std::vector<Device>::const_iterator it = devices.begin();
      it != devices.end(); ++it) {
    if (name == it->name) {
      *out = *it;
      return true;
    }
  }

  return false;
}

bool DeviceManager::GetAudioDevices(bool input,
                                    std::vector<Device>* devs) {
  devs->clear();
#ifdef ANDROID
  // Under Android, we don't access the device file directly.
  // Arbitrary use 0 for the mic and 1 for the output.
  // These ids are used in MediaEngine::SetSoundDevices(in, out);
  // The strings are for human consumption.
  if (input) {
      devs->push_back(Device("audiorecord", 0));
  } else {
      devs->push_back(Device("audiotrack", 1));
  }
  return true;
#else
  return false;
#endif
}

bool DeviceManager::GetAudioDevice(bool is_input, const std::string& name,
                                   Device* out) {
  // If the name is empty, return the default device id.
  if (name.empty() || name == kDefaultDeviceName) {
    *out = Device(name, -1);
    return true;
  }

  std::vector<Device> devices;
  bool ret = is_input ? GetAudioInputDevices(&devices) :
                        GetAudioOutputDevices(&devices);
  if (ret) {
    ret = false;
    for (size_t i = 0; i < devices.size(); ++i) {
      if (devices[i].name == name) {
        *out = devices[i];
        ret = true;
        break;
      }
    }
  }
  return ret;
}

bool DeviceManager::GetDefaultVideoCaptureDevice(Device* device) {
  bool ret = false;
  // We just return the first device.
  std::vector<Device> devices;
  ret = (GetVideoCaptureDevices(&devices) && !devices.empty());
  if (ret) {
    *device = devices[0];
  }
  return ret;
}

bool DeviceManager::ShouldDeviceBeIgnored(const std::string& device_name,
    const char* const exclusion_list[]) {
  // If exclusion_list is empty return directly.
  if (!exclusion_list)
    return false;

  int i = 0;
  while (exclusion_list[i]) {
    if (strnicmp(device_name.c_str(), exclusion_list[i],
        strlen(exclusion_list[i])) == 0) {
      LOG(LS_INFO) << "Ignoring device " << device_name;
      return true;
    }
    ++i;
  }
  return false;
}

bool DeviceManager::FilterDevices(std::vector<Device>* devices,
    const char* const exclusion_list[]) {
  if (!devices) {
    return false;
  }

  for (std::vector<Device>::iterator it = devices->begin();
       it != devices->end(); ) {
    if (ShouldDeviceBeIgnored(it->name, exclusion_list)) {
      it = devices->erase(it);
    } else {
      ++it;
    }
  }
  return true;
}

}  // namespace cricket
