/*
 * 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 "AbstractBlackBoxTestCase.h"
#import "TestResult.h"

@implementation AbstractBlackBoxTestCase

- (id)initWithInvocation:(NSInvocation *)invocation testBasePathSuffix:(NSString *)testBasePathSuffix barcodeReader:(id<ZXReader>)barcodeReader expectedFormat:(ZXBarcodeFormat)expectedFormat {
  if (self = [super initWithInvocation:invocation]) {
    _testBase = testBasePathSuffix;
    _barcodeReader = barcodeReader;
    _expectedFormat = expectedFormat;
    _testResults = [NSMutableArray array];
  }

  return self;
}

- (void)addTest:(int)mustPassCount tryHarderCount:(int)tryHarderCount rotation:(float)rotation {
  [self addTest:mustPassCount tryHarderCount:tryHarderCount maxMisreads:0 maxTryHarderMisreads:0 rotation:rotation];
}

/**
 * Adds a new test for the current directory of images.
 */
- (void)addTest:(int)mustPassCount tryHarderCount:(int)tryHarderCount maxMisreads:(int)maxMisreads maxTryHarderMisreads:(int)maxTryHarderMisreads rotation:(float)rotation {
  [self.testResults addObject:[[TestResult alloc] initWithMustPassCount:mustPassCount tryHarderCount:tryHarderCount maxMisreads:maxMisreads maxTryHarderMisreads:maxTryHarderMisreads rotation:rotation]];
}

- (NSArray *)imageFiles {
  NSMutableArray *imageFiles = [NSMutableArray array];
  for (NSString *file in [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:nil inDirectory:self.testBase]) {
    if ([[[file pathExtension] lowercaseString] isEqualToString:@"jpg"] ||
        [[[file pathExtension] lowercaseString] isEqualToString:@"jpeg"] ||
        [[[file pathExtension] lowercaseString] isEqualToString:@"gif"] ||
        [[[file pathExtension] lowercaseString] isEqualToString:@"png"]) {
      [imageFiles addObject:[NSURL fileURLWithPath:file]];
    }
  }

  return imageFiles;
}

- (void)runTests {
  [self testBlackBoxCountingResults:YES];
}

+ (NSString *)barcodeFormatAsString:(ZXBarcodeFormat)format {
  switch (format) {
    case kBarcodeFormatAztec:
      return @"Aztec";
      break;
    case kBarcodeFormatCodabar:
      return @"CODABAR";
      break;
    case kBarcodeFormatCode39:
      return @"Code 39";
      break;
    case kBarcodeFormatCode93:
      return @"Code 93";
      break;
    case kBarcodeFormatCode128:
      return @"Code 128";
      break;
    case kBarcodeFormatDataMatrix:
      return @"Data Matrix";
      break;
    case kBarcodeFormatEan8:
      return @"EAN-8";
      break;
    case kBarcodeFormatEan13:
      return @"EAN-13";
      break;
    case kBarcodeFormatITF:
      return @"ITF";
      break;
    case kBarcodeFormatMaxiCode:
      return @"MaxiCode";
      break;
    case kBarcodeFormatPDF417:
      return @"PDF417";
      break;
    case kBarcodeFormatQRCode:
      return @"QR Code";
      break;
    case kBarcodeFormatRSS14:
      return @"RSS 14";
      break;
    case kBarcodeFormatRSSExpanded:
      return @"RSS EXPANDED";
      break;
    case kBarcodeFormatUPCA:
      return @"UPC-A";
      break;
    case kBarcodeFormatUPCE:
      return @"UPC-E";
      break;
    case kBarcodeFormatUPCEANExtension:
      return @"UPC/EAN extension";
      break;
  }

  return nil;
}

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

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

  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSArray *imageFiles = [self imageFiles];
  int testCount = (int)[self.testResults count];

  int passedCounts[testCount];
  memset(passedCounts, 0, testCount * sizeof(int));

  int misreadCounts[testCount];
  memset(misreadCounts, 0, testCount * sizeof(int));

  int tryHarderCounts[testCount];
  memset(tryHarderCounts, 0, testCount * sizeof(int));

  int tryHarderMisreadCounts[testCount];
  memset(tryHarderMisreadCounts, 0, testCount * sizeof(int));

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

    NSString *testImageFileName = [[[testImage path] componentsSeparatedByString:@"/"] lastObject];
    NSString *fileBaseName = [testImageFileName substringToIndex:[testImageFileName rangeOfString:@"."].location];
    NSString *expectedTextFile = [[NSBundle bundleForClass:[self class]] pathForResource:fileBaseName ofType:@"txt" inDirectory:self.testBase];

    NSString *expectedText;
    if (expectedTextFile) {
      expectedText = [self readFileAsString:expectedTextFile encoding:NSUTF8StringEncoding];
    } else {
      NSString *expectedTextFile = [[NSBundle bundleForClass:[self class]] pathForResource:fileBaseName ofType:@"bin" inDirectory:self.testBase];
      STAssertNotNil(expectedTextFile, @"Expected text does not exist");
      expectedText = [self readFileAsString:expectedTextFile encoding:NSISOLatin1StringEncoding];
    }

    NSURL *expectedMetadataFile = [NSURL URLWithString:[[NSBundle bundleForClass:[self class]] pathForResource:fileBaseName ofType:@".metadata.txt" inDirectory:self.testBase]];
    NSMutableDictionary *expectedMetadata = [NSMutableDictionary dictionary];
    if ([fileManager fileExistsAtPath:[expectedMetadataFile path]]) {
      expectedMetadata = [NSMutableDictionary dictionaryWithContentsOfFile:[expectedMetadataFile path]];
    }

    for (int x = 0; x < testCount; x++) {
      float rotation = [(TestResult *)self.testResults[x] rotation];
      ZXImage *rotatedImage = [self rotateImage:image degrees:rotation];
      ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:rotatedImage.cgimage];
      ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXHybridBinarizer alloc] initWithSource:source]];
      BOOL misread;
      if ([self decode:bitmap rotation:rotation expectedText:expectedText expectedMetadata:expectedMetadata tryHarder:NO misread:&misread]) {
        passedCounts[x]++;
      } else if(misread) {
        misreadCounts[x]++;
      } else {
        NSLog(@"could not read at rotation %f", rotation);
      }

      if ([self decode:bitmap rotation:rotation expectedText:expectedText expectedMetadata:expectedMetadata tryHarder:YES misread:&misread]) {
        tryHarderCounts[x]++;
      } else if(misread) {
        tryHarderMisreadCounts[x]++;
      } else {
        NSLog(@"could not read at rotation %f w/TH", rotation);
      }
    }
  }

  // Print the results of all tests first
  int totalFound = 0;
  int totalMustPass = 0;
  int totalMisread = 0;
  int totalMaxMisread = 0;

  for (int x = 0; x < testCount; x++) {
    TestResult *testResult = self.testResults[x];
    NSLog(@"Rotation %d degrees:", (int) testResult.rotation);
    NSLog(@"  %d of %d images passed (%d required)",
          passedCounts[x], (int)imageFiles.count, testResult.mustPassCount);
    int failed = (int)imageFiles.count - passedCounts[x];
    NSLog(@"    %d failed due to misreads, %d not detected",
          misreadCounts[x], failed - misreadCounts[x]);
    NSLog(@"  %d of %d images passed with try harder (%d required)",
          tryHarderCounts[x], (int)imageFiles.count, testResult.tryHarderCount);
    failed = (int)imageFiles.count - tryHarderCounts[x];
    NSLog(@"    %d failed due to misreads, %d not detected",
          tryHarderMisreadCounts[x], failed - tryHarderMisreadCounts[x]);
    totalFound += passedCounts[x] + tryHarderCounts[x];
    totalMustPass += testResult.mustPassCount + testResult.tryHarderCount;
    totalMisread += misreadCounts[x] + tryHarderMisreadCounts[x];
    totalMaxMisread += testResult.maxMisreads + testResult.maxTryHarderMisreads;
  }

  int totalTests = (int)imageFiles.count * testCount * 2;
  NSLog(@"TOTALS:\nDecoded %d images out of %d (%d%%, %d required)",
        totalFound, totalTests, totalFound * 100 / totalTests, totalMustPass);
  if (totalFound > totalMustPass) {
    NSLog(@"  +++ Test too lax by %d images", totalFound - totalMustPass);
  } else if (totalFound < totalMustPass) {
    NSLog(@"  --- Test failed by %d images", totalMustPass - totalFound);
  }

  if (totalMisread < totalMaxMisread) {
    NSLog(@"  +++ Test expects too many misreads by %d images", totalMaxMisread - totalMisread);
  } else if (totalMisread > totalMaxMisread) {
    NSLog(@"  --- Test had too many misreads by %d images", totalMisread - totalMaxMisread);
  }

  // Then run through again and assert if any failed
  if (assertOnFailure) {
    for (int x = 0; x < testCount; x++) {
      TestResult *testResult = self.testResults[x];
      NSString *label = [NSString stringWithFormat:@"Rotation %f degrees: Too many images failed", testResult.rotation];
      STAssertTrue(passedCounts[x] >= testResult.mustPassCount, label);
      STAssertTrue(tryHarderCounts[x] >= testResult.tryHarderCount, @"Try harder, %@", label);
      label = [NSString stringWithFormat:@"Rotation %f degrees: Too many images misread", testResult.rotation];
      STAssertTrue(misreadCounts[x] <= testResult.maxMisreads, label);
      STAssertTrue(tryHarderMisreadCounts[x] <= testResult.maxTryHarderMisreads, @"Try harder, %@", label);
    }
  }
}

- (BOOL)decode:(ZXBinaryBitmap *)source rotation:(float)rotation expectedText:(NSString *)expectedText expectedMetadata:(NSMutableDictionary *)expectedMetadata tryHarder:(BOOL)tryHarder misread:(BOOL *)misread {
  NSString *suffix = [NSString stringWithFormat:@" (%@rotation: %d)", tryHarder ? @"try harder, " : @"", (int) rotation];
  *misread = NO;

  ZXDecodeHints *hints = [ZXDecodeHints hints];
  if (tryHarder) {
    hints.tryHarder = YES;
  }

  ZXResult *result = [self.barcodeReader decode:source hints:hints error:nil];
  if (!result) {
    return NO;
  }

  if (self.expectedFormat != result.barcodeFormat) {
    NSLog(@"Format mismatch: expected '%@' but got '%@'%@",
          [[self class] barcodeFormatAsString:self.expectedFormat], [[self class] barcodeFormatAsString:result.barcodeFormat], suffix);
    *misread = YES;
    return NO;
  }

  NSString *resultText = result.text;
  if (![expectedText isEqualToString:resultText]) {
    NSLog(@"Content mismatch: expected '%@' but got '%@'%@", expectedText, resultText, suffix);
    *misread = YES;
    return NO;
  }

  NSMutableDictionary *resultMetadata = result.resultMetadata;
  for (id keyObj in [expectedMetadata allKeys]) {
    ZXResultMetadataType key = [keyObj intValue];
    id expectedValue = expectedMetadata[keyObj];
    id actualValue = resultMetadata[keyObj];
    if (![expectedValue isEqual:actualValue]) {
      NSLog(@"Metadata mismatch: for key '%d' expected '%@' but got '%@'", key, expectedValue, actualValue);
      *misread = YES;
      return NO;
    }
  }

  return YES;
}

- (NSString *)readFileAsString:(NSString *)file encoding:(NSStringEncoding)encoding {
   NSString *stringContents = [NSString stringWithContentsOfFile:file encoding:encoding error:nil];
  if ([stringContents hasSuffix:@"\n"]) {
    NSLog(@"String contents of file %@ end with a newline. This may not be intended and cause a test failure", file);
  }
  return stringContents;
}

// Adapted from http://blog.coriolis.ch/2009/09/04/arbitrary-rotation-of-a-cgimage/ and https://github.com/JanX2/CreateRotateWriteCGImage
- (ZXImage *)rotateImage:(ZXImage *)original degrees:(float)degrees {
  if (degrees == 0.0f) {
    return original;
  }
  double radians = -1 * degrees * (M_PI / 180);

  CGRect imgRect = CGRectMake(0, 0, original.width, original.height);
  CGAffineTransform transform = CGAffineTransformMakeRotation(radians);
  CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);

  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = CGBitmapContextCreate(NULL,
                                               rotatedRect.size.width,
                                               rotatedRect.size.height,
                                               CGImageGetBitsPerComponent(original.cgimage),
                                               0,
                                               colorSpace,
                                               kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedFirst);
  CGContextSetAllowsAntialiasing(context, FALSE);
  CGContextSetInterpolationQuality(context, kCGInterpolationNone);
  CGColorSpaceRelease(colorSpace);

  CGContextTranslateCTM(context,
                        +(rotatedRect.size.width/2),
                        +(rotatedRect.size.height/2));
  CGContextRotateCTM(context, radians);

  CGContextDrawImage(context, CGRectMake(-imgRect.size.width/2, 
                                         -imgRect.size.height/2,
                                         imgRect.size.width, 
                                         imgRect.size.height),
                     original.cgimage);

  CGImageRef rotatedImage = CGBitmapContextCreateImage(context);

  CFRelease(context);

  return [[ZXImage alloc] initWithCGImageRef:rotatedImage];
}

@end
