/*

 Owner: Michael Ehrmann <michael@boinx.com>
 Company: Boinx Software Ltd., Germany
 Projects: BXQuartzComposer

 Abstract: Object describing a license key. Handles decryption of license key and gives access to its attributes.

 Related: <#related#>

 Documentation: <#link to documentation#>

 */

@import Foundation;

NS_ASSUME_NONNULL_BEGIN

#pragma mark - Debug

// define DEBUG_BXLICENSEKEY for debugging this file
// #define DEBUG_BXLICENSEKEY

#pragma mark - Filestrings

// define file strings
#define FILE_SUFIX @"BX"
#define FILE_EXTENSION @"license"

#pragma mark - Key-levels

// define key levels
#define LITE @"1"
#define DV @"2"
#define PRO @"3"
#define PROSUMER @"4"
#define HR @"5"
#define SPEZIAL @"6"
#define EXPRESS @"7"
#define HOME @"8"

#pragma mark - Key-types

// define key types
#define DEMO @"D"
#define NFR @"N"
#define PROMO @"P"
#define FAMILY @"F"
#define EDUCATION @"E"
#define SEEDING @"S"

#pragma mark - Key-fields (BXLicenseKeyProperty)

typedef NSString * BXLicenseKeyProperty NS_TYPED_ENUM;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyAppName;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyUsername;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyOrganisation;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyKey;
extern BXLicenseKeyProperty const BXLicenseKeyPropertySignature;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyExpirationNoteShown;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyVersionNumber;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyDateInstalled;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyDateUpdated;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyAppStoreReceipt;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyPath;
extern BXLicenseKeyProperty const BXLicenseKeyPropertyDomain;


#pragma mark - Key-results

//define key results
//#define APP_NAME @"A"
#define APP_KEY @"P"
#define APP_VERSION @"V"
#define USER_NAME @"U"
#define USER_ORGANISATION @"F"
#define KEY_LEVEL @"O"
#define KEY_TIMESPAN @"S"
#define KEY_TYPE @"T"
#define KEY_DEMO_OPTIONS @"D"
#define KEY_MODULES @"M"
#define KEY_EXPIRE_DATE @"E"
#define CUSTOMER_NUMBER @"C"
#define LICENSED_SEATS @"L"
#define FILE_PATH @"W"
#define INAPP_PURCHASE @"I"

#define IA_PRODUCT_NAME @"ProductName"
#define IA_PRODUCT_ID @"ProductID"
#define IA_PRODUCT_OBJECT @"ProductObject"

#define KEY_LEVEL_NAME @"KeyLevelName"

#pragma mark


@interface NSMutableAttributedString (RedHighlighting)
- (void)appendString:(NSString *)otherString highlight:(BOOL)highlight;
@end


@interface BXLicenseKey : NSObject

@property (nonatomic, readonly, class) NSDictionary *canonicalProductNames;

- (nullable instancetype)initWithDictionary:(NSDictionary*)dictionary internalExchange:(BOOL)inInternalExchange;
- (nullable instancetype)initWithDictionary:(NSDictionary *)dictionary;
- (nullable instancetype)initWithDictionaryFromDongle:(NSDictionary *)dictionary;
- (nullable instancetype)initWithKey:(NSString *)key name:(NSString *)name organisation:(NSString *)organisation;
- (nullable instancetype)initWithKey:(NSString*)key name:(NSString*)name organisation:(NSString*)organisation internalExchange:(BOOL)inInternalExchange;
- (nullable instancetype)initWithFile:(NSString *)path;

- (BOOL)saveLicenseKeyAtPath:(NSString *)path;
- (BOOL)loadLicenseKeyAtPath:(NSString *)path;
- (BOOL)removeFromFilesystem;

- (void)showInFinder:(id)inSender;

@property (readonly) NSString *stringValue;
@property (readonly) NSAttributedString *attributedStringValue;
- (NSAttributedString *)resultStringWithKeys:(NSString*)format makeLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;

- (NSAttributedString *)resultStringForUsernameWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForProductWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForVersionWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForCustomerNumberWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForKeyTypeWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForOptionsWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForKeyLevelWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForSeatsWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
//- (NSAttributedString *)resultStringForLocationWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForExpirationDateWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;
- (NSAttributedString *)resultStringForTimeSpanWithLineBreaks:(BOOL)makeLineBreaks withDescriptions:(BOOL)descriptions;

@property (nonatomic, readonly, strong) NSDictionary<BXLicenseKeyProperty, __kindof NSObject *> *licenseDict;
@property (nonatomic, readonly, strong, nullable) NSDictionary<NSString *, NSString *> *licenseResultDict;

@property (nonatomic, readonly) BOOL requiresSignature;
@property (nonatomic, readwrite) BOOL forcedExpiration;

@property (nonatomic, readonly, nullable) NSString *licenseProductName;
@property (nonatomic, readonly, nullable) NSString *canonicalLicenseProductName;
@property (nonatomic, readonly) NSString *licenseType;
@property (nonatomic, readonly, nullable) NSString *demoOptions;
@property (nonatomic, readonly, nullable) NSDate *expireDate;
@property (nonatomic, readonly, nullable) NSString *internalExchangeString;

@property (nonatomic, readonly) NSString *cleanLicenseKey;

@property (nonatomic, readonly, nullable) NSString *filePath;

@property (nonatomic, strong, nullable) NSDate *updatedOn;
@property (nonatomic) BOOL expirationNoteHasBeenDisplayed;

- (void)setKey:(NSString *)key name:(NSString *)name organisiation:(NSString *)organisation;

@property (nonatomic, readonly) BOOL isBoxLicense;
@property (nonatomic, readonly) BOOL isUnpersonalLicense;
@property (nonatomic, readonly) BOOL isJapaneseLicense;
@property (nonatomic, readonly) BOOL isDemo;
@property (nonatomic, readonly) BOOL isNFR;
@property (nonatomic, readonly) BOOL isInAppPurchase;
@property (nonatomic, readonly) BOOL isExpired;
@property (nonatomic, readonly) BOOL isTimeLimited;
@property (nonatomic, readonly) BOOL isStolen;
@property (nonatomic, readonly) BOOL isBlacklisted;
@property (nonatomic, readonly) BOOL isBetalicense;
@property (nonatomic, readonly) BOOL isDongleLicense;
@property (nonatomic, readonly) BOOL isUpdated;
@property (nonatomic, readonly) BOOL isInternalExchange;
@property (nonatomic, readonly) BOOL isAppStoreLicense;
@property (nonatomic, readonly) BOOL checkLicenseKey;
@property (nonatomic, readonly) BOOL stolenKey;
@property (nonatomic, readonly) BOOL knownKey;
@property (nonatomic, readonly) BOOL betaKey;
@property (nonatomic, readonly) BOOL knownNameOrg;

+ (nullable NSString *)shiftString:(NSString *)input withValue:(NSInteger)shift;
+ (nullable NSDate *)convertInternalDate:(nullable NSString *)date;
+ (NSString *)hexCharsOnly:(NSString *)fromString;

- (BOOL)hasBetterDemoOptionsAsLicense:(BXLicenseKey *)newLicenseKey;
- (BOOL)hasBetterOptionsAsLicense:(BXLicenseKey *)newLicenseKey;

@end

NS_ASSUME_NONNULL_END
