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

#import "APPRTCConnectionManager.h"

#import <AVFoundation/AVFoundation.h>
#import "APPRTCAppClient.h"
#import "GAEChannelClient.h"
#import "RTCICECandidate.h"
#import "RTCMediaConstraints.h"
#import "RTCMediaStream.h"
#import "RTCPair.h"
#import "RTCPeerConnection.h"
#import "RTCPeerConnectionDelegate.h"
#import "RTCPeerConnectionFactory.h"
#import "RTCSessionDescription.h"
#import "RTCSessionDescriptionDelegate.h"
#import "RTCStatsDelegate.h"
#import "RTCVideoCapturer.h"
#import "RTCVideoSource.h"

@interface APPRTCConnectionManager ()
    <APPRTCAppClientDelegate, GAEMessageHandler, RTCPeerConnectionDelegate,
     RTCSessionDescriptionDelegate, RTCStatsDelegate>

@property(nonatomic, strong) APPRTCAppClient* client;
@property(nonatomic, strong) RTCPeerConnection* peerConnection;
@property(nonatomic, strong) RTCPeerConnectionFactory* peerConnectionFactory;
@property(nonatomic, strong) RTCVideoSource* videoSource;
@property(nonatomic, strong) NSMutableArray* queuedRemoteCandidates;

@end

@implementation APPRTCConnectionManager {
  NSTimer* _statsTimer;
}

- (instancetype)initWithDelegate:(id<APPRTCConnectionManagerDelegate>)delegate
                          logger:(id<APPRTCLogger>)logger {
  if (self = [super init]) {
    self.delegate = delegate;
    self.logger = logger;
    self.peerConnectionFactory = [[RTCPeerConnectionFactory alloc] init];
    // TODO(tkchin): turn this into a button.
    // Uncomment for stat logs.
    // _statsTimer =
    //     [NSTimer scheduledTimerWithTimeInterval:10
    //                                      target:self
    //                                    selector:@selector(didFireStatsTimer:)
    //                                    userInfo:nil
    //                                     repeats:YES];
  }
  return self;
}

- (void)dealloc {
  [self disconnect];
}

- (BOOL)connectToRoomWithURL:(NSURL*)url {
  if (self.client) {
    // Already have a connection.
    return NO;
  }
  self.client = [[APPRTCAppClient alloc] initWithDelegate:self
                                           messageHandler:self];
  [self.client connectToRoom:url];
  return YES;
}

- (void)disconnect {
  if (!self.client) {
    return;
  }
  [self.client
      sendData:[@"{\"type\": \"bye\"}" dataUsingEncoding:NSUTF8StringEncoding]];
  [self.peerConnection close];
  self.peerConnection = nil;
  self.client = nil;
  self.queuedRemoteCandidates = nil;
}

#pragma mark - APPRTCAppClientDelegate

- (void)appClient:(APPRTCAppClient*)appClient
    didErrorWithMessage:(NSString*)message {
  [self.delegate connectionManager:self
               didErrorWithMessage:message];
}

- (void)appClient:(APPRTCAppClient*)appClient
    didReceiveICEServers:(NSArray*)servers {
  self.queuedRemoteCandidates = [NSMutableArray array];
  RTCMediaConstraints* constraints = [[RTCMediaConstraints alloc]
      initWithMandatoryConstraints:
          @[
            [[RTCPair alloc] initWithKey:@"OfferToReceiveAudio" value:@"true"],
            [[RTCPair alloc] initWithKey:@"OfferToReceiveVideo" value:@"true"]
          ]
               optionalConstraints:
                   @[
                     [[RTCPair alloc] initWithKey:@"internalSctpDataChannels"
                                            value:@"true"],
                     [[RTCPair alloc] initWithKey:@"DtlsSrtpKeyAgreement"
                                            value:@"true"]
                   ]];
  self.peerConnection =
      [self.peerConnectionFactory peerConnectionWithICEServers:servers
                                                   constraints:constraints
                                                      delegate:self];
  RTCMediaStream* lms =
      [self.peerConnectionFactory mediaStreamWithLabel:@"ARDAMS"];

  // The iOS simulator doesn't provide any sort of camera capture
  // support or emulation (http://goo.gl/rHAnC1) so don't bother
  // trying to open a local stream.
  RTCVideoTrack* localVideoTrack;

  // TODO(tkchin): local video capture for OSX. See
  // https://code.google.com/p/webrtc/issues/detail?id=3417.
#if !TARGET_IPHONE_SIMULATOR && TARGET_OS_IPHONE
  NSString* cameraID = nil;
  for (AVCaptureDevice* captureDevice in
       [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
    if (captureDevice.position == AVCaptureDevicePositionFront) {
      cameraID = [captureDevice localizedName];
      break;
    }
  }
  NSAssert(cameraID, @"Unable to get the front camera id");

  RTCVideoCapturer* capturer =
      [RTCVideoCapturer capturerWithDeviceName:cameraID];
  self.videoSource = [self.peerConnectionFactory
      videoSourceWithCapturer:capturer
                  constraints:self.client.videoConstraints];
  localVideoTrack =
      [self.peerConnectionFactory videoTrackWithID:@"ARDAMSv0"
                                            source:self.videoSource];
  if (localVideoTrack) {
    [lms addVideoTrack:localVideoTrack];
  }
  [self.delegate connectionManager:self
         didReceiveLocalVideoTrack:localVideoTrack];
#endif

  [lms addAudioTrack:[self.peerConnectionFactory audioTrackWithID:@"ARDAMSa0"]];
  [self.peerConnection addStream:lms constraints:constraints];
  [self.logger logMessage:@"onICEServers - added local stream."];
}

#pragma mark - GAEMessageHandler methods

- (void)onOpen {
  if (!self.client.initiator) {
    [self.logger logMessage:@"Callee; waiting for remote offer"];
    return;
  }
  [self.logger logMessage:@"GAE onOpen - create offer."];
  RTCPair* audio =
      [[RTCPair alloc] initWithKey:@"OfferToReceiveAudio" value:@"true"];
  RTCPair* video =
      [[RTCPair alloc] initWithKey:@"OfferToReceiveVideo" value:@"true"];
  NSArray* mandatory = @[ audio, video ];
  RTCMediaConstraints* constraints =
      [[RTCMediaConstraints alloc] initWithMandatoryConstraints:mandatory
                                            optionalConstraints:nil];
  [self.peerConnection createOfferWithDelegate:self constraints:constraints];
  [self.logger logMessage:@"PC - createOffer."];
}

- (void)onMessage:(NSDictionary*)messageData {
  NSString* type = messageData[@"type"];
  NSAssert(type, @"Missing type: %@", messageData);
  [self.logger logMessage:[NSString stringWithFormat:@"GAE onMessage type - %@",
                                                      type]];
  if ([type isEqualToString:@"candidate"]) {
    NSString* mid = messageData[@"id"];
    NSNumber* sdpLineIndex = messageData[@"label"];
    NSString* sdp = messageData[@"candidate"];
    RTCICECandidate* candidate =
        [[RTCICECandidate alloc] initWithMid:mid
                                       index:sdpLineIndex.intValue
                                         sdp:sdp];
    if (self.queuedRemoteCandidates) {
      [self.queuedRemoteCandidates addObject:candidate];
    } else {
      [self.peerConnection addICECandidate:candidate];
    }
  } else if ([type isEqualToString:@"offer"] ||
             [type isEqualToString:@"answer"]) {
    NSString* sdpString = messageData[@"sdp"];
    RTCSessionDescription* sdp = [[RTCSessionDescription alloc]
        initWithType:type
                 sdp:[[self class] preferISAC:sdpString]];
    [self.peerConnection setRemoteDescriptionWithDelegate:self
                                       sessionDescription:sdp];
    [self.logger logMessage:@"PC - setRemoteDescription."];
  } else if ([type isEqualToString:@"bye"]) {
    [self.delegate connectionManagerDidReceiveHangup:self];
  } else {
    NSAssert(NO, @"Invalid message: %@", messageData);
  }
}

- (void)onClose {
  [self.logger logMessage:@"GAE onClose."];
  [self.delegate connectionManagerDidReceiveHangup:self];
}

- (void)onError:(int)code withDescription:(NSString*)description {
  NSString* message = [NSString stringWithFormat:@"GAE onError: %d, %@",
                                code, description];
  [self.logger logMessage:message];
  [self.delegate connectionManager:self
               didErrorWithMessage:message];
}

#pragma mark - RTCPeerConnectionDelegate

- (void)peerConnectionOnError:(RTCPeerConnection*)peerConnection {
  dispatch_async(dispatch_get_main_queue(), ^{
    NSString* message = @"PeerConnection error";
    NSLog(@"%@", message);
    NSAssert(NO, @"PeerConnection failed.");
    [self.delegate connectionManager:self
                 didErrorWithMessage:message];
  });
}

- (void)peerConnection:(RTCPeerConnection*)peerConnection
    signalingStateChanged:(RTCSignalingState)stateChanged {
  dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"PCO onSignalingStateChange: %d", stateChanged);
  });
}

- (void)peerConnection:(RTCPeerConnection*)peerConnection
           addedStream:(RTCMediaStream*)stream {
  dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"PCO onAddStream.");
    NSAssert([stream.audioTracks count] == 1 || [stream.videoTracks count] == 1,
             @"Expected audio or video track");
    NSAssert([stream.audioTracks count] <= 1,
             @"Expected at most 1 audio stream");
    NSAssert([stream.videoTracks count] <= 1,
             @"Expected at most 1 video stream");
    if ([stream.videoTracks count] != 0) {
      [self.delegate connectionManager:self
            didReceiveRemoteVideoTrack:stream.videoTracks[0]];
    }
  });
}

- (void)peerConnection:(RTCPeerConnection*)peerConnection
         removedStream:(RTCMediaStream*)stream {
  dispatch_async(dispatch_get_main_queue(),
                 ^{ NSLog(@"PCO onRemoveStream."); });
}

- (void)peerConnectionOnRenegotiationNeeded:(RTCPeerConnection*)peerConnection {
  dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"PCO onRenegotiationNeeded - ignoring because AppRTC has a "
           "predefined negotiation strategy");
  });
}

- (void)peerConnection:(RTCPeerConnection*)peerConnection
       gotICECandidate:(RTCICECandidate*)candidate {
  dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"PCO onICECandidate.\n  Mid[%@] Index[%li] Sdp[%@]",
          candidate.sdpMid,
          (long)candidate.sdpMLineIndex,
          candidate.sdp);
    NSDictionary* json = @{
      @"type" : @"candidate",
      @"label" : @(candidate.sdpMLineIndex),
      @"id" : candidate.sdpMid,
      @"candidate" : candidate.sdp
    };
    NSError* error;
    NSData* data =
        [NSJSONSerialization dataWithJSONObject:json options:0 error:&error];
    if (!error) {
      [self.client sendData:data];
    } else {
      NSAssert(NO,
               @"Unable to serialize JSON object with error: %@",
               error.localizedDescription);
    }
  });
}

- (void)peerConnection:(RTCPeerConnection*)peerConnection
    iceGatheringChanged:(RTCICEGatheringState)newState {
  dispatch_async(dispatch_get_main_queue(),
                 ^{ NSLog(@"PCO onIceGatheringChange. %d", newState); });
}

- (void)peerConnection:(RTCPeerConnection*)peerConnection
    iceConnectionChanged:(RTCICEConnectionState)newState {
  dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"PCO onIceConnectionChange. %d", newState);
    if (newState == RTCICEConnectionConnected)
      [self.logger logMessage:@"ICE Connection Connected."];
    NSAssert(newState != RTCICEConnectionFailed, @"ICE Connection failed!");
  });
}

- (void)peerConnection:(RTCPeerConnection*)peerConnection
    didOpenDataChannel:(RTCDataChannel*)dataChannel {
  NSAssert(NO, @"AppRTC doesn't use DataChannels");
}

#pragma mark - RTCSessionDescriptionDelegate

- (void)peerConnection:(RTCPeerConnection*)peerConnection
    didCreateSessionDescription:(RTCSessionDescription*)origSdp
                          error:(NSError*)error {
  dispatch_async(dispatch_get_main_queue(), ^{
    if (error) {
      [self.logger logMessage:@"SDP onFailure."];
      NSAssert(NO, error.description);
      return;
    }
    [self.logger logMessage:@"SDP onSuccess(SDP) - set local description."];
    RTCSessionDescription* sdp = [[RTCSessionDescription alloc]
        initWithType:origSdp.type
                 sdp:[[self class] preferISAC:origSdp.description]];
    [self.peerConnection setLocalDescriptionWithDelegate:self
                                      sessionDescription:sdp];
    [self.logger logMessage:@"PC setLocalDescription."];
    NSDictionary* json = @{@"type" : sdp.type, @"sdp" : sdp.description};
    NSError* jsonError;
    NSData* data = [NSJSONSerialization dataWithJSONObject:json
                                                   options:0
                                                     error:&jsonError];
    NSAssert(!jsonError, @"Error: %@", jsonError.description);
    [self.client sendData:data];
  });
}

- (void)peerConnection:(RTCPeerConnection*)peerConnection
    didSetSessionDescriptionWithError:(NSError*)error {
  dispatch_async(dispatch_get_main_queue(), ^{
    if (error) {
      [self.logger logMessage:@"SDP onFailure."];
      NSAssert(NO, error.description);
      return;
    }
    [self.logger logMessage:@"SDP onSuccess() - possibly drain candidates"];
    if (!self.client.initiator) {
      if (self.peerConnection.remoteDescription &&
          !self.peerConnection.localDescription) {
        [self.logger logMessage:@"Callee, setRemoteDescription succeeded"];
        RTCPair* audio = [[RTCPair alloc] initWithKey:@"OfferToReceiveAudio"
                                                value:@"true"];
        RTCPair* video = [[RTCPair alloc] initWithKey:@"OfferToReceiveVideo"
                                                value:@"true"];
        NSArray* mandatory = @[ audio, video ];
        RTCMediaConstraints* constraints = [[RTCMediaConstraints alloc]
            initWithMandatoryConstraints:mandatory
                     optionalConstraints:nil];
        [self.peerConnection createAnswerWithDelegate:self
                                          constraints:constraints];
        [self.logger logMessage:@"PC - createAnswer."];
      } else {
        [self.logger logMessage:@"SDP onSuccess - drain candidates"];
        [self drainRemoteCandidates];
      }
    } else {
      if (self.peerConnection.remoteDescription) {
        [self.logger logMessage:@"SDP onSuccess - drain candidates"];
        [self drainRemoteCandidates];
      }
    }
  });
}

#pragma mark - RTCStatsDelegate methods

- (void)peerConnection:(RTCPeerConnection*)peerConnection
           didGetStats:(NSArray*)stats {
  dispatch_async(dispatch_get_main_queue(), ^{
    NSString* message = [NSString stringWithFormat:@"Stats:\n %@", stats];
    [self.logger logMessage:message];
  });
}

#pragma mark - Private

// Match |pattern| to |string| and return the first group of the first
// match, or nil if no match was found.
+ (NSString*)firstMatch:(NSRegularExpression*)pattern
             withString:(NSString*)string {
  NSTextCheckingResult* result =
      [pattern firstMatchInString:string
                          options:0
                            range:NSMakeRange(0, [string length])];
  if (!result)
    return nil;
  return [string substringWithRange:[result rangeAtIndex:1]];
}

// Mangle |origSDP| to prefer the ISAC/16k audio codec.
+ (NSString*)preferISAC:(NSString*)origSDP {
  int mLineIndex = -1;
  NSString* isac16kRtpMap = nil;
  NSArray* lines = [origSDP componentsSeparatedByString:@"\n"];
  NSRegularExpression* isac16kRegex = [NSRegularExpression
      regularExpressionWithPattern:@"^a=rtpmap:(\\d+) ISAC/16000[\r]?$"
                           options:0
                             error:nil];
  for (int i = 0;
       (i < [lines count]) && (mLineIndex == -1 || isac16kRtpMap == nil);
       ++i) {
    NSString* line = [lines objectAtIndex:i];
    if ([line hasPrefix:@"m=audio "]) {
      mLineIndex = i;
      continue;
    }
    isac16kRtpMap = [self firstMatch:isac16kRegex withString:line];
  }
  if (mLineIndex == -1) {
    NSLog(@"No m=audio line, so can't prefer iSAC");
    return origSDP;
  }
  if (isac16kRtpMap == nil) {
    NSLog(@"No ISAC/16000 line, so can't prefer iSAC");
    return origSDP;
  }
  NSArray* origMLineParts =
      [[lines objectAtIndex:mLineIndex] componentsSeparatedByString:@" "];
  NSMutableArray* newMLine =
      [NSMutableArray arrayWithCapacity:[origMLineParts count]];
  int origPartIndex = 0;
  // Format is: m=<media> <port> <proto> <fmt> ...
  [newMLine addObject:[origMLineParts objectAtIndex:origPartIndex++]];
  [newMLine addObject:[origMLineParts objectAtIndex:origPartIndex++]];
  [newMLine addObject:[origMLineParts objectAtIndex:origPartIndex++]];
  [newMLine addObject:isac16kRtpMap];
  for (; origPartIndex < [origMLineParts count]; ++origPartIndex) {
    if (![isac16kRtpMap
            isEqualToString:[origMLineParts objectAtIndex:origPartIndex]]) {
      [newMLine addObject:[origMLineParts objectAtIndex:origPartIndex]];
    }
  }
  NSMutableArray* newLines = [NSMutableArray arrayWithCapacity:[lines count]];
  [newLines addObjectsFromArray:lines];
  [newLines replaceObjectAtIndex:mLineIndex
                      withObject:[newMLine componentsJoinedByString:@" "]];
  return [newLines componentsJoinedByString:@"\n"];
}

- (void)drainRemoteCandidates {
  for (RTCICECandidate* candidate in self.queuedRemoteCandidates) {
    [self.peerConnection addICECandidate:candidate];
  }
  self.queuedRemoteCandidates = nil;
}

- (void)didFireStatsTimer:(NSTimer*)timer {
  if (self.peerConnection) {
    [self.peerConnection getStatsWithDelegate:self
                             mediaStreamTrack:nil
                             statsOutputLevel:RTCStatsOutputLevelDebug];
  }
}

@end
