//
//  TestBCSuffixArray.m
//  BioCocoa
//
//  Created by Scott Christley on 9/24/07.
//  Copyright (c) 2003-2009 The BioCocoa Project.
//  All rights reserved.
//
//  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 "TestBCSuffixArray.h"


@implementation TestBCSuffixArray

// test construct suffix array
#if 0
// disable for now as inMemory suffix array needs to be reworked
- (void)testMemoryConstructSuffixArray
{
  NSBundle *aBundle = [NSBundle bundleForClass: [self class]];
  NSString *fileName = [aBundle pathForResource: @"test" ofType: @"fa"];

  BCSuffixArray *anArray = [[BCSuffixArray alloc] init];

	// errors are concatenated
	NSMutableString *error=[NSMutableString stringWithString:@""];
  
  if (anArray == nil)
    [error appendString: @"Suffix array is nil\n"];
  else {
    // construct the suffix array
    if (![anArray constructFromSequenceFile: fileName strand: nil])
      [error appendString: @"Error while constructing suffix array\n"];

    if ([anArray numberOfSequences] != 2)
      [error appendFormat: @"Number of sequence in array is incorrect, 2 != %d\n", [anArray numberOfSequences]];
    else {
      BCSequenceArray *sequenceArray = [anArray sequenceArray];
      NSDictionary *metaDictionary = [anArray metaDictionary];
      if (metaDictionary == nil)
        [error appendString: @"Meta dictionary is nil\n"];
      else {
        if ([[metaDictionary objectForKey: @"length"] intValue] != 619)
          [error appendFormat: @"Total length of sequences is incorrect, 619 != %@\n", [metaDictionary objectForKey: @"length"]];

        BCSequence *aSeq = [sequenceArray sequenceAtIndex: 0];
        if ([aSeq length] != 517)
          [error appendFormat: @"Length of sequence is incorrect, 517 != %d\n", [aSeq length]];
      }
    }
  }

	// if error!=@"", the test failed
	STAssertTrue ([error isEqualToString:@""], error);
}
#endif

// test construct suffix array
- (void)testFileConstructSuffixArray
{
  NSBundle *aBundle = [NSBundle bundleForClass: [self class]];
  NSString *fileName = [aBundle pathForResource: @"test" ofType: @"fa"];

  // delete temporary files
  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSString *s = [fileName stringByAppendingPathExtension: @"sa"];
  if ([fileManager fileExistsAtPath: s]) [fileManager removeFileAtPath: s handler: nil];
  s = [fileName stringByAppendingPathExtension: @"meta_sa"];
  if ([fileManager fileExistsAtPath: s]) [fileManager removeFileAtPath: s handler: nil];

  BCSuffixArray *anArray = [[BCSuffixArray alloc] init];

	// errors are concatenated
	NSMutableString *error=[NSMutableString stringWithString:@""];
  
  if (anArray == nil)
    [error appendString: @"Suffix array is nil\n"];
  else {
    // construct the suffix array
    if (![anArray constructFromSequenceFile: fileName strand: nil])
      [error appendString: @"Error while constructing suffix array\n"];

    // write to disk
    if (![anArray writeToFile: fileName withMasking: YES])
      [error appendFormat: @"Error while writing suffix array to file: %@\n", fileName];
    [anArray release];

    // read from disk
    anArray = [[BCSuffixArray alloc] initWithContentsOfFile: fileName inMemory: NO];
    if (anArray == nil)
      [error appendFormat: @"Could not read suffix array from file: %@\n", fileName];
    else {
      if ([anArray numberOfSequences] != 2)
        [error appendFormat: @"Number of sequence in array is incorrect, 2 != %d\n", [anArray numberOfSequences]];
      else {
        BCSequenceArray *sequenceArray = [anArray sequenceArray];
        NSDictionary *metaDictionary = [anArray metaDictionary];
        if (metaDictionary == nil)
          [error appendString: @"Meta-dictionary is nil\n"];
        else {
          if ([[metaDictionary objectForKey: @"length"] intValue] != 619)
            [error appendFormat: @"Total length of sequences in meta-dictionary is incorrect, 619 != %@\n",
              [metaDictionary objectForKey: @"length"]];

          NSArray *seqs = [metaDictionary objectForKey: @"sequences"];
          if (!seqs) [error appendString: @"Meta-dictionary missing sequences\n"];

          NSDictionary *d = [seqs objectAtIndex: 0];
          int aValue = [[d objectForKey: @"length"] intValue];
          if (aValue != 517)
            [error appendFormat: @"Length of sequence in meta-dictionary is incorrect, 517 != %d\n", aValue];
          aValue = [[d objectForKey: @"number"] intValue];
          if (aValue != 0)
            [error appendFormat: @"Sequence number in meta-dictionary is incorrect, 0 != %d\n", aValue];

          d = [seqs objectAtIndex: 1];
          aValue = [[d objectForKey: @"length"] intValue];
          if (aValue != 102)
            [error appendFormat: @"Length of sequence in meta-dictionary is incorrect, 102 != %d\n", aValue];
          aValue = [[d objectForKey: @"number"] intValue];
          if (aValue != 1)
            [error appendFormat: @"Sequence number in meta-dictionary is incorrect, 1 != %d\n", aValue];

          BCSequence *aSeq = [sequenceArray sequenceAtIndex: 0];
          if ([aSeq length] != 517)
            [error appendFormat: @"Length of sequence is incorrect, 517 != %d\n", [aSeq length]];

          aSeq = [sequenceArray sequenceAtIndex: 1];
          if ([aSeq length] != 102)
            [error appendFormat: @"Length of sequence is incorrect, 102 != %d\n", [aSeq length]];
          
        }
      }
    }
  }

	// if error!=@"", the test failed
	STAssertTrue ([error isEqualToString:@""], error);
}

@end
