/*
 * 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.
 */

#import <Foundation/Foundation.h>

#import "RTCICEServer.h"
#import "RTCMediaConstraints.h"
#import "RTCMediaStream.h"
#import "RTCPair.h"
#import "RTCPeerConnection.h"
#import "RTCPeerConnectionFactory.h"
#import "RTCPeerConnectionSyncObserver.h"
#import "RTCSessionDescription.h"
#import "RTCSessionDescriptionSyncObserver.h"
#import "RTCVideoRenderer.h"
#import "RTCVideoTrack.h"

#include "webrtc/base/gunit.h"
#include "webrtc/base/ssladapter.h"

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

@interface RTCFakeRenderer : NSObject <RTCVideoRenderer>
@end

@implementation RTCFakeRenderer

- (void)setSize:(CGSize)size {}
- (void)renderFrame:(RTCI420Frame*)frame {}

@end

@interface RTCPeerConnectionTest : NSObject

// Returns whether the two sessions are of the same type.
+ (BOOL)isSession:(RTCSessionDescription*)session1
    ofSameTypeAsSession:(RTCSessionDescription*)session2;

// Create and add tracks to pc, with the given source, label, and IDs
- (RTCMediaStream*)addTracksToPeerConnection:(RTCPeerConnection*)pc
                                 withFactory:(RTCPeerConnectionFactory*)factory
                                 videoSource:(RTCVideoSource*)videoSource
                                 streamLabel:(NSString*)streamLabel
                                videoTrackID:(NSString*)videoTrackID
                                audioTrackID:(NSString*)audioTrackID;

- (void)testCompleteSessionWithFactory:(RTCPeerConnectionFactory*)factory;

@end

@implementation RTCPeerConnectionTest

+ (BOOL)isSession:(RTCSessionDescription*)session1
    ofSameTypeAsSession:(RTCSessionDescription*)session2 {
  return [session1.type isEqual:session2.type];
}

- (RTCMediaStream*)addTracksToPeerConnection:(RTCPeerConnection*)pc
                                 withFactory:(RTCPeerConnectionFactory*)factory
                                 videoSource:(RTCVideoSource*)videoSource
                                 streamLabel:(NSString*)streamLabel
                                videoTrackID:(NSString*)videoTrackID
                                audioTrackID:(NSString*)audioTrackID {
  RTCMediaStream* localMediaStream = [factory mediaStreamWithLabel:streamLabel];
  RTCVideoTrack* videoTrack =
      [factory videoTrackWithID:videoTrackID source:videoSource];
  RTCFakeRenderer* videoRenderer = [[RTCFakeRenderer alloc] init];
  [videoTrack addRenderer:videoRenderer];
  [localMediaStream addVideoTrack:videoTrack];
  // Test that removal/re-add works.
  [localMediaStream removeVideoTrack:videoTrack];
  [localMediaStream addVideoTrack:videoTrack];
  RTCAudioTrack* audioTrack = [factory audioTrackWithID:audioTrackID];
  [localMediaStream addAudioTrack:audioTrack];
  [pc addStream:localMediaStream];
  return localMediaStream;
}

- (void)testCompleteSessionWithFactory:(RTCPeerConnectionFactory*)factory {
  NSArray* mandatory = @[
    [[RTCPair alloc] initWithKey:@"DtlsSrtpKeyAgreement" value:@"true"],
    [[RTCPair alloc] initWithKey:@"internalSctpDataChannels" value:@"true"],
  ];
  RTCMediaConstraints* constraints = [[RTCMediaConstraints alloc] init];
  RTCMediaConstraints* pcConstraints =
      [[RTCMediaConstraints alloc] initWithMandatoryConstraints:mandatory
                                            optionalConstraints:nil];

  RTCPeerConnectionSyncObserver* offeringExpectations =
      [[RTCPeerConnectionSyncObserver alloc] init];
  RTCPeerConnection* pcOffer =
      [factory peerConnectionWithICEServers:nil
                                constraints:pcConstraints
                                   delegate:offeringExpectations];

  RTCPeerConnectionSyncObserver* answeringExpectations =
      [[RTCPeerConnectionSyncObserver alloc] init];

  RTCPeerConnection* pcAnswer =
      [factory peerConnectionWithICEServers:nil
                                constraints:pcConstraints
                                   delegate:answeringExpectations];
  // TODO(hughv): Create video capturer
  RTCVideoCapturer* capturer = nil;
  RTCVideoSource* videoSource =
      [factory videoSourceWithCapturer:capturer constraints:constraints];

  // Here and below, "oLMS" refers to offerer's local media stream, and "aLMS"
  // refers to the answerer's local media stream, with suffixes of "a0" and "v0"
  // for audio and video tracks, resp.  These mirror chrome historical naming.
  RTCMediaStream* oLMSUnused = [self addTracksToPeerConnection:pcOffer
                                                   withFactory:factory
                                                   videoSource:videoSource
                                                   streamLabel:@"oLMS"
                                                  videoTrackID:@"oLMSv0"
                                                  audioTrackID:@"oLMSa0"];

  RTCDataChannel* offerDC =
      [pcOffer createDataChannelWithLabel:@"offerDC"
                                   config:[[RTCDataChannelInit alloc] init]];
  EXPECT_TRUE([offerDC.label isEqual:@"offerDC"]);
  offerDC.delegate = offeringExpectations;
  offeringExpectations.dataChannel = offerDC;

  RTCSessionDescriptionSyncObserver* sdpObserver =
      [[RTCSessionDescriptionSyncObserver alloc] init];
  [pcOffer createOfferWithDelegate:sdpObserver constraints:constraints];
  [sdpObserver wait];
  EXPECT_TRUE(sdpObserver.success);
  RTCSessionDescription* offerSDP = sdpObserver.sessionDescription;
  EXPECT_EQ([@"offer" compare:offerSDP.type options:NSCaseInsensitiveSearch],
            NSOrderedSame);
  EXPECT_GT([offerSDP.description length], 0);

  sdpObserver = [[RTCSessionDescriptionSyncObserver alloc] init];
  [answeringExpectations expectSignalingChange:RTCSignalingHaveRemoteOffer];
  [answeringExpectations expectAddStream:@"oLMS"];
  [pcAnswer setRemoteDescriptionWithDelegate:sdpObserver
                          sessionDescription:offerSDP];
  [sdpObserver wait];

  RTCMediaStream* aLMSUnused = [self addTracksToPeerConnection:pcAnswer
                                                   withFactory:factory
                                                   videoSource:videoSource
                                                   streamLabel:@"aLMS"
                                                  videoTrackID:@"aLMSv0"
                                                  audioTrackID:@"aLMSa0"];

  sdpObserver = [[RTCSessionDescriptionSyncObserver alloc] init];
  [pcAnswer createAnswerWithDelegate:sdpObserver constraints:constraints];
  [sdpObserver wait];
  EXPECT_TRUE(sdpObserver.success);
  RTCSessionDescription* answerSDP = sdpObserver.sessionDescription;
  EXPECT_EQ([@"answer" compare:answerSDP.type options:NSCaseInsensitiveSearch],
            NSOrderedSame);
  EXPECT_GT([answerSDP.description length], 0);

  [offeringExpectations expectICECandidates:2];
  [answeringExpectations expectICECandidates:2];

  sdpObserver = [[RTCSessionDescriptionSyncObserver alloc] init];
  [answeringExpectations expectSignalingChange:RTCSignalingStable];
  [pcAnswer setLocalDescriptionWithDelegate:sdpObserver
                         sessionDescription:answerSDP];
  [sdpObserver wait];
  EXPECT_TRUE(sdpObserver.sessionDescription == NULL);

  sdpObserver = [[RTCSessionDescriptionSyncObserver alloc] init];
  [offeringExpectations expectSignalingChange:RTCSignalingHaveLocalOffer];
  [pcOffer setLocalDescriptionWithDelegate:sdpObserver
                        sessionDescription:offerSDP];
  [sdpObserver wait];
  EXPECT_TRUE(sdpObserver.sessionDescription == NULL);

  [offeringExpectations expectICEConnectionChange:RTCICEConnectionChecking];
  [offeringExpectations expectICEConnectionChange:RTCICEConnectionConnected];
  // TODO(fischman): figure out why this is flaky and re-introduce (and remove
  // special-casing from the observer!).
  // [offeringExpectations expectICEConnectionChange:RTCICEConnectionCompleted];
  [answeringExpectations expectICEConnectionChange:RTCICEConnectionChecking];
  [answeringExpectations expectICEConnectionChange:RTCICEConnectionConnected];

  [offeringExpectations expectStateChange:kRTCDataChannelStateOpen];
  [answeringExpectations expectDataChannel:@"offerDC"];
  [answeringExpectations expectStateChange:kRTCDataChannelStateOpen];

  [offeringExpectations expectICEGatheringChange:RTCICEGatheringComplete];
  [answeringExpectations expectICEGatheringChange:RTCICEGatheringComplete];

  sdpObserver = [[RTCSessionDescriptionSyncObserver alloc] init];
  [offeringExpectations expectSignalingChange:RTCSignalingStable];
  [offeringExpectations expectAddStream:@"aLMS"];
  [pcOffer setRemoteDescriptionWithDelegate:sdpObserver
                         sessionDescription:answerSDP];
  [sdpObserver wait];
  EXPECT_TRUE(sdpObserver.sessionDescription == NULL);

  EXPECT_TRUE([offerSDP.type isEqual:pcOffer.localDescription.type]);
  EXPECT_TRUE([answerSDP.type isEqual:pcOffer.remoteDescription.type]);
  EXPECT_TRUE([offerSDP.type isEqual:pcAnswer.remoteDescription.type]);
  EXPECT_TRUE([answerSDP.type isEqual:pcAnswer.localDescription.type]);

  for (RTCICECandidate* candidate in offeringExpectations
           .releaseReceivedICECandidates) {
    [pcAnswer addICECandidate:candidate];
  }
  for (RTCICECandidate* candidate in answeringExpectations
           .releaseReceivedICECandidates) {
    [pcOffer addICECandidate:candidate];
  }

  [offeringExpectations waitForAllExpectationsToBeSatisfied];
  [answeringExpectations waitForAllExpectationsToBeSatisfied];

  EXPECT_EQ(pcOffer.signalingState, RTCSignalingStable);
  EXPECT_EQ(pcAnswer.signalingState, RTCSignalingStable);

  // Test send and receive UTF-8 text
  NSString* text = @"你好";
  NSData* textData = [text dataUsingEncoding:NSUTF8StringEncoding];
  RTCDataBuffer* buffer =
      [[RTCDataBuffer alloc] initWithData:textData isBinary:NO];
  [answeringExpectations expectMessage:[textData copy] isBinary:NO];
  EXPECT_TRUE([offeringExpectations.dataChannel sendData:buffer]);
  [answeringExpectations waitForAllExpectationsToBeSatisfied];

  // Test send and receive binary data
  const size_t byteLength = 5;
  char bytes[byteLength] = {1, 2, 3, 4, 5};
  NSData* byteData = [NSData dataWithBytes:bytes length:byteLength];
  buffer = [[RTCDataBuffer alloc] initWithData:byteData isBinary:YES];
  [answeringExpectations expectMessage:[byteData copy] isBinary:YES];
  EXPECT_TRUE([offeringExpectations.dataChannel sendData:buffer]);
  [answeringExpectations waitForAllExpectationsToBeSatisfied];

  [offeringExpectations expectStateChange:kRTCDataChannelStateClosing];
  [answeringExpectations expectStateChange:kRTCDataChannelStateClosing];
  [offeringExpectations expectStateChange:kRTCDataChannelStateClosed];
  [answeringExpectations expectStateChange:kRTCDataChannelStateClosed];

  [answeringExpectations.dataChannel close];
  [offeringExpectations.dataChannel close];

  [offeringExpectations waitForAllExpectationsToBeSatisfied];
  [answeringExpectations waitForAllExpectationsToBeSatisfied];
  // Don't need to listen to further state changes.
  // TODO(tkchin): figure out why Closed->Closing without this.
  offeringExpectations.dataChannel.delegate = nil;
  answeringExpectations.dataChannel.delegate = nil;

  // Let the audio feedback run for 2s to allow human testing and to ensure
  // things stabilize.  TODO(fischman): replace seconds with # of video frames,
  // when we have video flowing.
  [[NSRunLoop currentRunLoop]
      runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];

  [offeringExpectations expectICEConnectionChange:RTCICEConnectionClosed];
  [answeringExpectations expectICEConnectionChange:RTCICEConnectionClosed];
  [offeringExpectations expectSignalingChange:RTCSignalingClosed];
  [answeringExpectations expectSignalingChange:RTCSignalingClosed];

  [pcOffer close];
  [pcAnswer close];

  [offeringExpectations waitForAllExpectationsToBeSatisfied];
  [answeringExpectations waitForAllExpectationsToBeSatisfied];

  capturer = nil;
  videoSource = nil;
  pcOffer = nil;
  pcAnswer = nil;
  // TODO(fischman): be stricter about shutdown checks; ensure thread
  // counts return to where they were before the test kicked off, and
  // that all objects have in fact shut down.
}

@end

// TODO(fischman): move {Initialize,Cleanup}SSL into alloc/dealloc of
// RTCPeerConnectionTest and avoid the appearance of RTCPeerConnectionTest being
// a TestBase since it's not.
TEST(RTCPeerConnectionTest, SessionTest) {
  @autoreleasepool {
    rtc::InitializeSSL();
    // Since |factory| will own the signaling & worker threads, it's important
    // that it outlive the created PeerConnections since they self-delete on the
    // signaling thread, and if |factory| is freed first then a last refcount on
    // the factory will expire during this teardown, causing the signaling
    // thread to try to Join() with itself.  This is a hack to ensure that the
    // factory outlives RTCPeerConnection:dealloc.
    // See https://code.google.com/p/webrtc/issues/detail?id=3100.
    RTCPeerConnectionFactory* factory = [[RTCPeerConnectionFactory alloc] init];
    @autoreleasepool {
      RTCPeerConnectionTest* pcTest = [[RTCPeerConnectionTest alloc] init];
      [pcTest testCompleteSessionWithFactory:factory];
    }
    rtc::CleanupSSL();
  }
}
