// Protocol Buffers - Google's data interchange format
// Copyright 2014 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * 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.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "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 COPYRIGHT
// OWNER OR CONTRIBUTORS 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 "GPBTestUtilities.h"

#import "objectivec/Tests/Unittest.pbobjc.h"
#import "objectivec/Tests/UnittestObjc.pbobjc.h"

static const int kNumThreads = 100;
static const int kNumMessages = 100;

// NOTE: Most of these tests don't "fail" in the sense that the XCTAsserts
// trip.  Rather, the asserts simply exercise the apis, and if there is
// a concurancy issue, the NSAsserts in the runtime code fire and/or the
// code just crashes outright.

@interface ConcurrencyTests : GPBTestCase
@end

@implementation ConcurrencyTests

- (NSArray *)createThreadsWithSelector:(SEL)selector object:(id)object {
  NSMutableArray *array = [NSMutableArray array];
  for (NSUInteger i = 0; i < kNumThreads; i++) {
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:selector object:object];
    [array addObject:thread];
    [thread release];
  }
  return array;
}

- (NSArray *)createMessagesWithType:(Class)msgType {
  NSMutableArray *array = [NSMutableArray array];
  for (NSUInteger i = 0; i < kNumMessages; i++) {
    [array addObject:[msgType message]];
  }
  return array;
}

- (void)startThreads:(NSArray *)threads {
  for (NSThread *thread in threads) {
    [thread start];
  }
}

- (void)joinThreads:(NSArray *)threads {
  for (NSThread *thread in threads) {
    while (![thread isFinished])
      ;
  }
}

- (void)readForeignMessage:(NSArray *)messages {
  for (NSUInteger i = 0; i < 10; i++) {
    for (TestAllTypes *message in messages) {
      XCTAssertEqual(message.optionalForeignMessage.c, 0);
    }
  }
}

- (void)testConcurrentReadOfUnsetMessageField {
  NSArray *messages = [self createMessagesWithType:[TestAllTypes class]];
  NSArray *threads = [self createThreadsWithSelector:@selector(readForeignMessage:)
                                              object:messages];
  [self startThreads:threads];
  [self joinThreads:threads];
  for (TestAllTypes *message in messages) {
    XCTAssertFalse(message.hasOptionalForeignMessage);
  }
}

- (void)readRepeatedInt32:(NSArray *)messages {
  for (int i = 0; i < 10; i++) {
    for (TestAllTypes *message in messages) {
      XCTAssertEqual([message.repeatedInt32Array count], (NSUInteger)0);
    }
  }
}

- (void)testConcurrentReadOfUnsetRepeatedIntField {
  NSArray *messages = [self createMessagesWithType:[TestAllTypes class]];
  NSArray *threads = [self createThreadsWithSelector:@selector(readRepeatedInt32:) object:messages];
  [self startThreads:threads];
  [self joinThreads:threads];
  for (TestAllTypes *message in messages) {
    XCTAssertEqual([message.repeatedInt32Array count], (NSUInteger)0);
  }
}

- (void)readRepeatedString:(NSArray *)messages {
  for (int i = 0; i < 10; i++) {
    for (TestAllTypes *message in messages) {
      XCTAssertEqual([message.repeatedStringArray count], (NSUInteger)0);
    }
  }
}

- (void)testConcurrentReadOfUnsetRepeatedStringField {
  NSArray *messages = [self createMessagesWithType:[TestAllTypes class]];
  NSArray *threads = [self createThreadsWithSelector:@selector(readRepeatedString:)
                                              object:messages];
  [self startThreads:threads];
  [self joinThreads:threads];
  for (TestAllTypes *message in messages) {
    XCTAssertEqual([message.repeatedStringArray count], (NSUInteger)0);
  }
}

- (void)readInt32Int32Map:(NSArray *)messages {
  for (int i = 0; i < 10; i++) {
    for (TestRecursiveMessageWithRepeatedField *message in messages) {
      XCTAssertEqual([message.iToI count], (NSUInteger)0);
    }
  }
}

- (void)testConcurrentReadOfUnsetInt32Int32MapField {
  NSArray *messages = [self createMessagesWithType:[TestRecursiveMessageWithRepeatedField class]];
  NSArray *threads = [self createThreadsWithSelector:@selector(readInt32Int32Map:) object:messages];
  [self startThreads:threads];
  [self joinThreads:threads];
  for (TestRecursiveMessageWithRepeatedField *message in messages) {
    XCTAssertEqual([message.iToI count], (NSUInteger)0);
  }
}

- (void)readStringStringMap:(NSArray *)messages {
  for (int i = 0; i < 10; i++) {
    for (TestRecursiveMessageWithRepeatedField *message in messages) {
      XCTAssertEqual([message.strToStr count], (NSUInteger)0);
    }
  }
}

- (void)testConcurrentReadOfUnsetStringStringMapField {
  NSArray *messages = [self createMessagesWithType:[TestRecursiveMessageWithRepeatedField class]];
  NSArray *threads = [self createThreadsWithSelector:@selector(readStringStringMap:)
                                              object:messages];
  [self startThreads:threads];
  [self joinThreads:threads];
  for (TestRecursiveMessageWithRepeatedField *message in messages) {
    XCTAssertEqual([message.strToStr count], (NSUInteger)0);
  }
}

- (void)readOptionalForeignMessageExtension:(NSArray *)messages {
  for (int i = 0; i < 10; i++) {
    for (TestAllExtensions *message in messages) {
      ForeignMessage *foreign =
          [message getExtension:[UnittestRoot optionalForeignMessageExtension]];
      XCTAssertEqual(foreign.c, 0);
    }
  }
}

- (void)testConcurrentReadOfUnsetExtensionField {
  NSArray *messages = [self createMessagesWithType:[TestAllExtensions class]];
  SEL sel = @selector(readOptionalForeignMessageExtension:);
  NSArray *threads = [self createThreadsWithSelector:sel object:messages];
  [self startThreads:threads];
  [self joinThreads:threads];
  GPBExtensionDescriptor *extension = [UnittestRoot optionalForeignMessageExtension];
  for (TestAllExtensions *message in messages) {
    XCTAssertFalse([message hasExtension:extension]);
  }
}

@end
