/*
 *  Copyright (c) 2012 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 "modules/video_capture/device_info_impl.h"

#include <stdlib.h>

#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "rtc_base/logging.h"

#ifndef abs
#define abs(a) (a >= 0 ? a : -a)
#endif

namespace webrtc {
namespace videocapturemodule {

DeviceInfoImpl::DeviceInfoImpl()
    : _lastUsedDeviceName(NULL), _lastUsedDeviceNameLength(0) {}

DeviceInfoImpl::~DeviceInfoImpl(void) {
  MutexLock lock(&_apiLock);
  free(_lastUsedDeviceName);
}

int32_t DeviceInfoImpl::NumberOfCapabilities(const char* deviceUniqueIdUTF8) {
  if (!deviceUniqueIdUTF8)
    return -1;

  MutexLock lock(&_apiLock);

  // Is it the same device that is asked for again.
  if (absl::EqualsIgnoreCase(
          deviceUniqueIdUTF8,
          absl::string_view(_lastUsedDeviceName, _lastUsedDeviceNameLength))) {
    return static_cast<int32_t>(_captureCapabilities.size());
  }

  int32_t ret = CreateCapabilityMap(deviceUniqueIdUTF8);
  return ret;
}

int32_t DeviceInfoImpl::GetCapability(const char* deviceUniqueIdUTF8,
                                      const uint32_t deviceCapabilityNumber,
                                      VideoCaptureCapability& capability) {
  RTC_DCHECK(deviceUniqueIdUTF8);

  MutexLock lock(&_apiLock);

  if (!absl::EqualsIgnoreCase(
          deviceUniqueIdUTF8,
          absl::string_view(_lastUsedDeviceName, _lastUsedDeviceNameLength))) {
    if (-1 == CreateCapabilityMap(deviceUniqueIdUTF8)) {
      return -1;
    }
  }

  // Make sure the number is valid
  if (deviceCapabilityNumber >= (unsigned int)_captureCapabilities.size()) {
    RTC_LOG(LS_ERROR) << "Invalid deviceCapabilityNumber "
                      << deviceCapabilityNumber << ">= number of capabilities ("
                      << _captureCapabilities.size() << ").";
    return -1;
  }

  capability = _captureCapabilities[deviceCapabilityNumber];
  return 0;
}

int32_t DeviceInfoImpl::GetBestMatchedCapability(
    const char* deviceUniqueIdUTF8,
    const VideoCaptureCapability& requested,
    VideoCaptureCapability& resulting) {
  if (!deviceUniqueIdUTF8)
    return -1;

  MutexLock lock(&_apiLock);
  if (!absl::EqualsIgnoreCase(
          deviceUniqueIdUTF8,
          absl::string_view(_lastUsedDeviceName, _lastUsedDeviceNameLength))) {
    if (-1 == CreateCapabilityMap(deviceUniqueIdUTF8)) {
      return -1;
    }
  }

  int32_t bestformatIndex = -1;
  int32_t bestWidth = 0;
  int32_t bestHeight = 0;
  int32_t bestFrameRate = 0;
  VideoType bestVideoType = VideoType::kUnknown;

  const int32_t numberOfCapabilies =
      static_cast<int32_t>(_captureCapabilities.size());

  for (int32_t tmp = 0; tmp < numberOfCapabilies;
       ++tmp)  // Loop through all capabilities
  {
    VideoCaptureCapability& capability = _captureCapabilities[tmp];

    const int32_t diffWidth = capability.width - requested.width;
    const int32_t diffHeight = capability.height - requested.height;
    const int32_t diffFrameRate = capability.maxFPS - requested.maxFPS;

    const int32_t currentbestDiffWith = bestWidth - requested.width;
    const int32_t currentbestDiffHeight = bestHeight - requested.height;
    const int32_t currentbestDiffFrameRate = bestFrameRate - requested.maxFPS;

    if ((diffHeight >= 0 &&
         diffHeight <= abs(currentbestDiffHeight))  // Height better or equalt
                                                    // that previouse.
        || (currentbestDiffHeight < 0 && diffHeight >= currentbestDiffHeight)) {
      if (diffHeight ==
          currentbestDiffHeight)  // Found best height. Care about the width)
      {
        if ((diffWidth >= 0 &&
             diffWidth <= abs(currentbestDiffWith))  // Width better or equal
            || (currentbestDiffWith < 0 && diffWidth >= currentbestDiffWith)) {
          if (diffWidth == currentbestDiffWith &&
              diffHeight == currentbestDiffHeight)  // Same size as previously
          {
            // Also check the best frame rate if the diff is the same as
            // previouse
            if (((diffFrameRate >= 0 &&
                  diffFrameRate <=
                      currentbestDiffFrameRate)  // Frame rate to high but
                                                 // better match than previouse
                                                 // and we have not selected IUV
                 || (currentbestDiffFrameRate < 0 &&
                     diffFrameRate >=
                         currentbestDiffFrameRate))  // Current frame rate is
                                                     // lower than requested.
                                                     // This is better.
            ) {
              if ((currentbestDiffFrameRate ==
                   diffFrameRate)  // Same frame rate as previous  or frame rate
                                   // allready good enough
                  || (currentbestDiffFrameRate >= 0)) {
                if (bestVideoType != requested.videoType &&
                    requested.videoType != VideoType::kUnknown &&
                    (capability.videoType == requested.videoType ||
                     capability.videoType == VideoType::kI420 ||
                     capability.videoType == VideoType::kYUY2 ||
                     capability.videoType == VideoType::kYV12 ||
                     capability.videoType == VideoType::kNV12)) {
                  bestVideoType = capability.videoType;
                  bestformatIndex = tmp;
                }
                // If width height and frame rate is full filled we can use the
                // camera for encoding if it is supported.
                if (capability.height == requested.height &&
                    capability.width == requested.width &&
                    capability.maxFPS >= requested.maxFPS) {
                  bestformatIndex = tmp;
                }
              } else  // Better frame rate
              {
                bestWidth = capability.width;
                bestHeight = capability.height;
                bestFrameRate = capability.maxFPS;
                bestVideoType = capability.videoType;
                bestformatIndex = tmp;
              }
            }
          } else  // Better width than previously
          {
            bestWidth = capability.width;
            bestHeight = capability.height;
            bestFrameRate = capability.maxFPS;
            bestVideoType = capability.videoType;
            bestformatIndex = tmp;
          }
        }     // else width no good
      } else  // Better height
      {
        bestWidth = capability.width;
        bestHeight = capability.height;
        bestFrameRate = capability.maxFPS;
        bestVideoType = capability.videoType;
        bestformatIndex = tmp;
      }
    }  // else height not good
  }    // end for

  RTC_LOG(LS_VERBOSE) << "Best camera format: " << bestWidth << "x"
                      << bestHeight << "@" << bestFrameRate
                      << "fps, color format: "
                      << static_cast<int>(bestVideoType);

  // Copy the capability
  if (bestformatIndex < 0)
    return -1;
  resulting = _captureCapabilities[bestformatIndex];
  return bestformatIndex;
}

// Default implementation. This should be overridden by Mobile implementations.
int32_t DeviceInfoImpl::GetOrientation(const char* /* deviceUniqueIdUTF8 */,
                                       VideoRotation& orientation) {
  orientation = kVideoRotation_0;
  return -1;
}
}  // namespace videocapturemodule
}  // namespace webrtc
