// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "media/video/capture/mac/avfoundation_glue.h"

#include <dlfcn.h>

#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/mac/mac_util.h"
#include "media/base/media_switches.h"

namespace {

// This class is used to retrieve AVFoundation NSBundle and library handle. It
// must be used as a LazyInstance so that it is initialised once and in a
// thread-safe way. Normally no work is done in constructors: LazyInstance is
// an exception.
class AVFoundationInternal {
 public:
  AVFoundationInternal() {
    bundle_ = [NSBundle
        bundleWithPath:@"/System/Library/Frameworks/AVFoundation.framework"];

    const char* path = [[bundle_ executablePath] fileSystemRepresentation];
    CHECK(path);
    library_handle_ = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
    CHECK(library_handle_) << dlerror();
  }
  NSBundle* bundle() const { return bundle_; }
  void* library_handle() const { return library_handle_; }

 private:
  NSBundle* bundle_;
  void* library_handle_;

  DISALLOW_COPY_AND_ASSIGN(AVFoundationInternal);
};

}  // namespace

static base::LazyInstance<AVFoundationInternal> g_avfoundation_handle =
    LAZY_INSTANCE_INITIALIZER;

namespace media {

// TODO(mcasas):http://crbug.com/323536 cache the string pointers.
static NSString* ReadNSStringPtr(const char* symbol) {
  NSString** string_pointer = reinterpret_cast<NSString**>(
      dlsym(AVFoundationGlue::AVFoundationLibraryHandle(), symbol));
  DCHECK(string_pointer) << dlerror();
  return *string_pointer;
}

}  // namespace media

bool AVFoundationGlue::IsAVFoundationSupported() {
  const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
  return !cmd_line->HasSwitch(switches::kDisableAVFoundation) &&
      base::mac::IsOSLionOrLater() && [AVFoundationBundle() load];
}

NSBundle const* AVFoundationGlue::AVFoundationBundle() {
  return g_avfoundation_handle.Get().bundle();
}

void* AVFoundationGlue::AVFoundationLibraryHandle() {
  return g_avfoundation_handle.Get().library_handle();
}

NSString* AVFoundationGlue::AVCaptureDeviceWasConnectedNotification() {
  return media::ReadNSStringPtr("AVCaptureDeviceWasConnectedNotification");
}

NSString* AVFoundationGlue::AVCaptureDeviceWasDisconnectedNotification() {
  return media::ReadNSStringPtr("AVCaptureDeviceWasDisconnectedNotification");
}

NSString* AVFoundationGlue::AVMediaTypeVideo() {
  return media::ReadNSStringPtr("AVMediaTypeVideo");
}

NSString* AVFoundationGlue::AVMediaTypeAudio() {
  return media::ReadNSStringPtr("AVMediaTypeAudio");
}

NSString* AVFoundationGlue::AVMediaTypeMuxed() {
  return media::ReadNSStringPtr("AVMediaTypeMuxed");
}

NSString* AVFoundationGlue::AVCaptureSessionRuntimeErrorNotification() {
  return media::ReadNSStringPtr("AVCaptureSessionRuntimeErrorNotification");
}

NSString* AVFoundationGlue::AVCaptureSessionDidStopRunningNotification() {
  return media::ReadNSStringPtr("AVCaptureSessionDidStopRunningNotification");
}

NSString* AVFoundationGlue::AVCaptureSessionErrorKey() {
  return media::ReadNSStringPtr("AVCaptureSessionErrorKey");
}

NSString* AVFoundationGlue::AVCaptureSessionPreset320x240() {
  return media::ReadNSStringPtr("AVCaptureSessionPreset320x240");
}

NSString* AVFoundationGlue::AVCaptureSessionPreset640x480() {
  return media::ReadNSStringPtr("AVCaptureSessionPreset640x480");
}

NSString* AVFoundationGlue::AVCaptureSessionPreset1280x720() {
  return media::ReadNSStringPtr("AVCaptureSessionPreset1280x720");
}

NSString* AVFoundationGlue::AVVideoScalingModeKey() {
  return media::ReadNSStringPtr("AVVideoScalingModeKey");
}

NSString* AVFoundationGlue::AVVideoScalingModeResizeAspect() {
  return media::ReadNSStringPtr("AVVideoScalingModeResizeAspect");
}

Class AVFoundationGlue::AVCaptureSessionClass() {
  return [AVFoundationBundle() classNamed:@"AVCaptureSession"];
}

Class AVFoundationGlue::AVCaptureVideoDataOutputClass() {
  return [AVFoundationBundle() classNamed:@"AVCaptureVideoDataOutput"];
}

@implementation AVCaptureDeviceGlue

+ (NSArray*)devices {
  Class avcClass =
      [AVFoundationGlue::AVFoundationBundle() classNamed:@"AVCaptureDevice"];
  if ([avcClass respondsToSelector:@selector(devices)]) {
    return [avcClass performSelector:@selector(devices)];
  }
  return nil;
}

+ (CrAVCaptureDevice*)deviceWithUniqueID:(NSString*)deviceUniqueID {
  Class avcClass =
      [AVFoundationGlue::AVFoundationBundle() classNamed:@"AVCaptureDevice"];
  return [avcClass performSelector:@selector(deviceWithUniqueID:)
                        withObject:deviceUniqueID];
}

@end  // @implementation AVCaptureDeviceGlue

@implementation AVCaptureDeviceInputGlue

+ (CrAVCaptureDeviceInput*)deviceInputWithDevice:(CrAVCaptureDevice*)device
                                           error:(NSError**)outError {
  return [[AVFoundationGlue::AVFoundationBundle()
      classNamed:@"AVCaptureDeviceInput"] deviceInputWithDevice:device
                                                          error:outError];
}

@end  // @implementation AVCaptureDeviceInputGlue
