/*
 * 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();
  }
}
