//
//  ZSMConfig.h
//  ZSM
//
//  Created by Joel Teply on 8/9/23.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

/**
 * Enum representing the various loging levels.
 */
typedef NS_ENUM(NSInteger, LogLevel) {
    LogLevelTrace=-1, /**< Used for trace logging. */
    LogLevelDebug, /**< Used for debugging purposes. This level of logging provides the most granular information. */
    LogLevelInfo, /**< Used to record informational messages that highlight the progress of the application at a high level. */
    LogLevelWarn, /**< Indicates potentially harmful situations. */
    LogLevelError, /**< Used to record error events that might still allow the application to continue running.*/
    LogLevelFatal /**< Records very severe error events that will presumably lead the application to abort. */
};

/**
 * Enum representing the various encryption algorithms.
 */
typedef NS_ENUM(NSInteger, MPCAlgorithm) {
    MPCAlgorithmECDSAP256=0x10,
    MPCAlgorithmRSA2048=0x20,
    MPCAlgorithmRSA3072=0x21,
    MPCAlgorithmRSA4096=0x22,
    MPCAlgorithmAES128ECB=0x30,
    MPCAlgorithmAES128CTR=0x31,
};

/**
 * This block is called whenever a log message is created.
 * @param level The log level of the message.
 * @param message The log message.
 */
typedef void (^ZSMLoggingCallback)(LogLevel level, NSString * message);

@interface ZSMConfig : NSObject <NSCopying> {
    NSDateFormatter *_timestampFormatter;
}

    /**
     * Instantiates a ZSM config instance with the specified host URL and consumer ID.
     * @param json configuration json
     * @return A newly initialized ZSMConfig instance.
     */
    - (nullable instancetype)initWithJSON:(NSDictionary *)json;

    /**
     * Host url for performing remote transactions
     */
    @property (strong, nonatomic, nonnull) NSURL *hostUrl;

    /**
     * Host url for performing fido authentication
     */
    @property (strong, nonatomic, nonnull) NSURL *authenticationHostUrl;

    /**
     * Region identifier (e.g., "demo", "us1", "eu1"). Can be provided directly or derived from host_url pattern.
     */
    @property (strong, nonatomic, nullable) NSString *region;

    /**
     * Application ID for remote transactions
     */
    @property (strong, nonatomic, nonnull) NSUUID *applicationId;

    
    @property (strong, nonatomic, nonnull) NSUUID *apiKey;

    /**
     * Network timeout while performing remote transactions. Default's to 30 seconds or 30000 ms
     */
    @property (assign, nonatomic) NSUInteger requestTimeoutMS;

    /**
     * Network retry count while performing remote transactions. Default's to 0
     */
    @property (assign, nonatomic) NSUInteger retryCount;

    /**
     * Whether to perform a health check prior to instantiation to test for network health. Defaults to true.
     */
    @property (assign, nonatomic) BOOL performNetworkHealthCheck;

    /**
     * Optional environment name
     */
    @property (strong, nonatomic, nullable) NSString *applicationEnvironment;

    /**
     * Headers used while performing remote transactions
     */
    @property (strong, nonatomic) NSMutableDictionary *headers;

    /**
     * meta data used while performing remote transactions
     */
    @property (strong, nonatomic) NSMutableDictionary *metadata;

    /**
     * consumer ID for remote transactions
     */
    @property (strong, nonatomic, nonnull) NSString *consumerId;

    /**
     * identity ID for identifying a user's identity
     */
    @property (strong, nonatomic, nullable) NSString *identityId;

    /**
     * Optional custom domain for passkey RP ID. If not provided, defaults to authenticationHostUrl.host
     */
    @property (strong, nonatomic, nullable) NSString *passkeyRpId;

    /**
     * Whether to require biometric authentication for MPC credentials.
     * Default: NO (biometrics not required)
     * When YES: MPC credentials require biometric authentication for storage and usage
     * When NO: MPC credentials can be used without biometrics
     * Note: This setting is separate from PasskeysPlus biometrics (handled by passkeys)
     */
    @property (assign, nonatomic) BOOL requiresBiometrics;

    /**
     * Whether to defer registration/finish to customer's server (default: YES)
     * When YES: SDK returns credential without finalizing, customer calls validate-token
     *           validate-token handles finish internally and validates the credential
     * When NO: SDK calls registration/finish automatically (legacy behavior)
     */
    @property (assign, nonatomic) BOOL deferRegistrationFinish;

    /**
     * Whether to defer authentication/finish to customer's server (default: YES)
     * When YES: SDK returns assertion without finalizing, customer calls validate-token
     * When NO: SDK calls authentication/finish automatically (legacy behavior)
     */
    @property (assign, nonatomic) BOOL deferAuthenticationFinish;

    /**
      Shared keychain group ID between multiple applications of the same vendor.
      The format is typically 'keychainGroup' or 'TEAMID.keychainGroup', where 'keychainGroup' is specified as an entry in your app's Target Settings -> Keychain Sharing -> Keychain Groups. 'TEAMID' is your iOS Development Team ID, found in your iOS provisioning portal or as the string 'DEVELOPMENT_TEAM' within the project file.
      The necessity of including 'TEAMID' in the format can vary based on your app's configuration and provisioning. For detailed guidelines on setting up and using keychain access groups, consult Apple's documentation on this subject: https://developer.apple.com/documentation/bundleresources/entitlements/keychain-access-groups
    */
    @property (strong, nonatomic, nullable) NSString *keychainGroup;

    
    /**
     * encryption algorithm for transactions. Defaults to MpcAlgorithmECDSAP256
     */
    @property (assign, nonatomic) MPCAlgorithm mpcAlgorithm;

    /**
     * level for api logging
     */
    @property (assign, nonatomic) LogLevel logLevel;
    
    /**
     * A block that will be called whenever a log message is created.
     */
    @property (copy, nonatomic) ZSMLoggingCallback logFunction;
@end

/**
 * Utility functions for log level conversion
 */
NSString * _Nullable logLevelToString(LogLevel logLevel);
LogLevel logLevelFromString(NSString * _Nullable logLevelString, LogLevel defaultLevel);

NS_ASSUME_NONNULL_END
