/*
 * libjingle
 * Copyright 2013 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.
 */

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

#import "RTCMediaStream+Internal.h"

#import "RTCAudioTrack+Internal.h"
#import "RTCMediaStreamTrack+Internal.h"
#import "RTCVideoTrack+Internal.h"

#include "talk/app/webrtc/mediastreaminterface.h"

@implementation RTCMediaStream {
  NSMutableArray* _audioTracks;
  NSMutableArray* _videoTracks;
  rtc::scoped_refptr<webrtc::MediaStreamInterface> _mediaStream;
}

- (NSString*)description {
  return [NSString stringWithFormat:@"[%@:A=%lu:V=%lu]",
                                    [self label],
                                    (unsigned long)[self.audioTracks count],
                                    (unsigned long)[self.videoTracks count]];
}

- (NSArray*)audioTracks {
  return [_audioTracks copy];
}

- (NSArray*)videoTracks {
  return [_videoTracks copy];
}

- (NSString*)label {
  return @(self.mediaStream->label().c_str());
}

- (BOOL)addAudioTrack:(RTCAudioTrack*)track {
  if (self.mediaStream->AddTrack(track.audioTrack)) {
    [_audioTracks addObject:track];
    return YES;
  }
  return NO;
}

- (BOOL)addVideoTrack:(RTCVideoTrack*)track {
  if (self.mediaStream->AddTrack(track.nativeVideoTrack)) {
    [_videoTracks addObject:track];
    return YES;
  }
  return NO;
}

- (BOOL)removeAudioTrack:(RTCAudioTrack*)track {
  NSUInteger index = [_audioTracks indexOfObjectIdenticalTo:track];
  NSAssert(index != NSNotFound,
           @"|removeAudioTrack| called on unexpected RTCAudioTrack");
  if (index != NSNotFound && self.mediaStream->RemoveTrack(track.audioTrack)) {
    [_audioTracks removeObjectAtIndex:index];
    return YES;
  }
  return NO;
}

- (BOOL)removeVideoTrack:(RTCVideoTrack*)track {
  NSUInteger index = [_videoTracks indexOfObjectIdenticalTo:track];
  NSAssert(index != NSNotFound,
           @"|removeAudioTrack| called on unexpected RTCVideoTrack");
  if (index != NSNotFound &&
      self.mediaStream->RemoveTrack(track.nativeVideoTrack)) {
    [_videoTracks removeObjectAtIndex:index];
    return YES;
  }
  return NO;
}

@end

@implementation RTCMediaStream (Internal)

- (id)initWithMediaStream:
          (rtc::scoped_refptr<webrtc::MediaStreamInterface>)mediaStream {
  if (!mediaStream) {
    NSAssert(NO, @"nil arguments not allowed");
    self = nil;
    return nil;
  }
  if ((self = [super init])) {
    webrtc::AudioTrackVector audio_tracks = mediaStream->GetAudioTracks();
    webrtc::VideoTrackVector video_tracks = mediaStream->GetVideoTracks();

    _audioTracks = [NSMutableArray arrayWithCapacity:audio_tracks.size()];
    _videoTracks = [NSMutableArray arrayWithCapacity:video_tracks.size()];
    _mediaStream = mediaStream;

    for (size_t i = 0; i < audio_tracks.size(); ++i) {
      rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
          audio_tracks[i];
      RTCAudioTrack* audioTrack =
          [[RTCAudioTrack alloc] initWithMediaTrack:track];
      [_audioTracks addObject:audioTrack];
    }

    for (size_t i = 0; i < video_tracks.size(); ++i) {
      rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
          video_tracks[i];
      RTCVideoTrack* videoTrack =
          [[RTCVideoTrack alloc] initWithMediaTrack:track];
      [_videoTracks addObject:videoTrack];
    }
  }
  return self;
}

- (rtc::scoped_refptr<webrtc::MediaStreamInterface>)mediaStream {
  return _mediaStream;
}

@end
