//
//  DTASN1SerializationTest.m
//  DTFoundation
//
//  Created by Oliver Drobnik on 3/9/13.
//  Copyright (c) 2013 Cocoanetics. All rights reserved.
//

#import "DTASN1SerializationTest.h"

#if !TARGET_OS_WATCH

#import "DTASN1BitString.h"

@import DTFoundation;

@implementation DTASN1SerializationTest

- (void)testDeserialization
{
	NSString *string = @"MBaAFDxB4o8ICKlMJYmNbcU40PyFjGIX";
	NSData *data = [DTBase64Coding dataByDecodingString:string];
	
	id object = [DTASN1Serialization objectWithData:data];
	
	XCTAssertNotNil(object, @"Should be able to decode as array");
	XCTAssertTrue([object isKindOfClass:[NSArray class]], @"Decoded object should be an array");
}

- (void)testBitString
{
	NSString *string = @"AwIFoA==";
	NSData *data = [DTBase64Coding dataByDecodingString:string];

	DTASN1BitString *bitString = [DTASN1Serialization objectWithData:data];
	
	NSString *asString = [bitString stringWithBits];
	XCTAssertTrue([@"101" isEqualToString:asString], @"Result should be 101");
}

- (void)testUTF8String
{
	NSString *string = @"DApTb21lLVN0YXRl";
	NSData *data = [DTBase64Coding dataByDecodingString:string];
    
	NSString *decodedString = [DTASN1Serialization objectWithData:data];
	
	XCTAssertTrue([@"Some-State" isEqualToString:decodedString], @"Result is not 'Some-State'");
}

// a sequence with no contents should still be returned as array
- (void)testDecodingEmptySequence
{
	NSString *string = @"MAA=";
	NSData *data = [DTBase64Coding dataByDecodingString:string];
	
	id object = [DTASN1Serialization objectWithData:data];
	
	XCTAssertNotNil(object, @"Should be able to decode as array");
	XCTAssertTrue([object isKindOfClass:[NSArray class]], @"Decoded object should be an array");
}

- (void)testDecodingSimpleInt
{
    NSMutableData *data = [NSMutableData new];
    uint8_t byte = 2;
    [data appendBytes:&byte length:1];
    byte = 1;
    [data appendBytes:&byte length:1];
    byte = 3;
    [data appendBytes:&byte length:1];
    
    NSNumber *object = [DTASN1Serialization objectWithData:data];
    XCTAssertEqualObjects(object, @(3));
}

- (void)testDecodingLongInt
{
    NSString *string = @"AgcDjX6mjTpM";
    NSData *data = [DTBase64Coding dataByDecodingString:string];
    
    NSNumber *object = [DTASN1Serialization objectWithData:data];
    
    XCTAssertNotNil(object, @"Should be able to decode as number");
    XCTAssertTrue([object isKindOfClass:[NSNumber class]], @"Decoded object should be a number");
    XCTAssertEqualObjects(object, @(1000000029801036));
}

- (void)testDecodingEmptyString
{
    NSString *string = @"FgA=";
    NSData *data = [DTBase64Coding dataByDecodingString:string];
    
    NSString *object = [DTASN1Serialization objectWithData:data];
    
    XCTAssertNotNil(object, @"Should be able to decode as number");
    XCTAssertTrue([object isKindOfClass:[NSString class]], @"Decoded object should be a string");
    XCTAssertEqualObjects(object, @"");
}

- (void)testCertificateDecoding
{
    NSString *path = [self pathForTestResource:@"SelfSigned" ofType:@"der"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    
    id object = [DTASN1Serialization objectWithData:data];
    
	XCTAssertNotNil(object, @"Should be able to decode certificate");
    
    XCTAssertTrue([object isKindOfClass:[NSArray class]], @"Certficate should be decoded as NSArray");
    XCTAssertEqual([object count], (NSUInteger)3, @"Certificate should have 3 sections");
}

#pragma mark - Helper

- (NSString *)pathForTestResource:(nullable NSString *)name ofType:(nullable NSString *)ext
{
	NSBundle *testBundle = [NSBundle bundleForClass:[self class]];

#if SWIFT_PACKAGE
	NSURL *url = [[[testBundle bundleURL] URLByDeletingLastPathComponent] URLByAppendingPathComponent:@"DTFoundation_DTFoundationTests.bundle"];
	NSBundle *resourceBundle = [NSBundle bundleWithURL:url];
	NSString *finalPath = [resourceBundle pathForResource:name ofType:ext];
#else
	NSString *finalPath = [testBundle pathForResource:name ofType:ext];
#endif
	
	return finalPath;
}

@end

#endif
