/*
 * Copyright 2012 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#import "AbstractNegativeBlackBoxTestCase.h"

@interface NegativeTestResult : NSObject

@property (nonatomic, assign) int falsePositivesAllowed;
@property (nonatomic, assign) float rotation;

@end

@implementation NegativeTestResult

- (id)initWithFalsePositivesAllowed:(int)falsePositivesAllowed rotation:(float)rotation {
  if (self = [super init]) {
    _falsePositivesAllowed = falsePositivesAllowed;
    _rotation = rotation;
  }

  return self;
}

@end

@implementation AbstractNegativeBlackBoxTestCase

// Use the multiformat reader to evaluate all decoders in the system.
- (id)initWithInvocation:(NSInvocation *)invocation testBasePathSuffix:(NSString *)testBasePathSuffix {
  if (self = [super initWithInvocation:invocation testBasePathSuffix:testBasePathSuffix barcodeReader:[[ZXMultiFormatReader alloc] init] expectedFormat:0]) {
    self.testResults = [NSMutableArray array];
  }

  return self;
}

- (void)addTest:(int)falsePositivesAllowed rotation:(float)rotation {
  [self.testResults addObject:[[NegativeTestResult alloc] initWithFalsePositivesAllowed:falsePositivesAllowed rotation:rotation]];
}

- (NSString *)pathInBundle:(NSURL *)file {
  NSInteger startOfResources = [[file path] rangeOfString:@"Resources"].location;
  if (startOfResources == NSNotFound) {
    return [file path];
  } else {
    return [[file path] substringFromIndex:startOfResources];
  }
}

- (void)runTests {
  if (self.testResults.count == 0) {
    STFail(@"No test results");
  }

  NSArray *imageFiles = [self imageFiles];

  int falsePositives[self.testResults.count];
  memset(falsePositives, 0, self.testResults.count * sizeof(int));

  for (NSURL *testImage in imageFiles) {
    NSLog(@"Starting %@", [self pathInBundle:testImage]);

    ZXImage *image = [[ZXImage alloc] initWithURL:testImage];
    for (int x = 0; x < self.testResults.count; x++) {
      NegativeTestResult *testResult = self.testResults[x];
      if (![self checkForFalsePositives:image rotationInDegrees:testResult.rotation]) {
        falsePositives[x]++;
      }
    }
  }

  int totalFalsePositives = 0;
  int totalAllowed = 0;

  for (int x = 0; x < self.testResults.count; x++) {
    NegativeTestResult *testResult = self.testResults[x];
    totalFalsePositives += falsePositives[x];
    totalAllowed += testResult.falsePositivesAllowed;
  }

  if (totalFalsePositives < totalAllowed) {
    NSLog(@"  +++ Test too lax by %d images", totalAllowed - totalFalsePositives);
  } else if (totalFalsePositives > totalAllowed) {
    NSLog(@"  --- Test failed by %d images", totalFalsePositives - totalAllowed);
  }

  for (int x = 0; x < self.testResults.count; x++) {
    NegativeTestResult *testResult = self.testResults[x];
    NSLog(@"Rotation %d degrees: %d of %d images were false positives (%d allowed)",
          (int)testResult.rotation, falsePositives[x], (int)imageFiles.count,
          testResult.falsePositivesAllowed);
    STAssertTrue(falsePositives[x] <= testResult.falsePositivesAllowed,
                 @"Rotation %f degrees: Too many false positives found", testResult.rotation);
  }
}

/**
 * Make sure ZXing does NOT find a barcode in the image.
 */
- (BOOL)checkForFalsePositives:(ZXImage *)image rotationInDegrees:(CGFloat)rotationInDegrees {
  ZXImage *rotatedImage = [self rotateImage:image degrees:rotationInDegrees];
  ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:rotatedImage.cgimage];
  ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXHybridBinarizer alloc] initWithSource:source]];
  NSError *error = nil;
  ZXResult *result = [self.barcodeReader decode:bitmap error:&error];
  if (result) {
    NSLog(@"Found false positive: '%@' with format '%@' (rotation: %d)",
          result.text, [AbstractBlackBoxTestCase barcodeFormatAsString:result.barcodeFormat], (int) rotationInDegrees);
    return NO;
  }

  // Try "try harder" getMode
  ZXDecodeHints *hints = [ZXDecodeHints hints];
  hints.tryHarder = YES;
  result = [self.barcodeReader decode:bitmap hints:hints error:&error];
  if (result) {
    NSLog(@"Try harder found false positive: '%@' with format '%@' (rotation: %d)",
          result.text, [AbstractBlackBoxTestCase barcodeFormatAsString:result.barcodeFormat], (int) rotationInDegrees);
    return NO;
  }
  return YES;
}

@end
