//
//  BPSAuthenticationHelper.h
//  BPAdmin
//
//  Created by Alykhan Jetha on 2013-10-14.
//
//

#import <Foundation/Foundation.h>
#import <MCClientServer/MCSSharedConstants.h>
#import <MCClientServer/MCClientServerDefines.h>

@class MCPGDatabase;
@class MCHostedServer;
@class MCHostingNode;

/*!
 These authentication methods have moved from BPAccessdEndpoint because multiple objects need access (touchd, staged and accessd). With the old method, we connected to accessd from touchd, staged, the apps and of course accessd. This is simply unnecessary for touchd and staged as all those components already have the right PG connection. On self-serve, this is not a problem, but on cloud, this all adds up.
 
 When you use these methods, please ensure that you pass in valid objects in a valid state. These methods don't do much error checking in order to efficient.
 */
@interface BPSAuthenticationHelper : NSObject


/*!
 Given a username (name) and password, returns by reference a raw pg dictionary (no camelcase) representing the user. Verifies the username, password and active in one call. Expects exactly one matching entry.
 */
+ (MCSAuthorizationResultCode)getUserRepresentation:(NSDictionary **)rep
                                        forUsername:(NSString *)aUsername
                                           password:(NSString *)rawPassword
                                           database:(MCPGDatabase *)db;


/*!
 Given the client uuid, returns by reference a raw pg dictionary representing the replicant. Only checks the client uuid as that should be unique enough. Expects exactly one matching entry or none. Return kMCSAuthorizationResultUnknownError multiple are found. If none is found, then one is created.
 */
+ (MCSAuthorizationResultCode)getReplicantRepresentation:(NSDictionary **)rep
                                           forClientUUID:(NSString *)aUUID
                                      userRepresentation:(NSDictionary *)userRep
                                                 request:(NSDictionary *)payload
                                                database:(MCPGDatabase *)db;

/*!
 Gets the replicant regardless of user or type
 */
+ (MCSAuthorizationResultCode)getReplicantRepresentation:(NSDictionary **)rep
                                           forClientUUID:(NSString *)aUUID
                                                database:(MCPGDatabase *)db;

/*!
 Gets the replicant using the offset regardless of user or type
 */
+ (MCSAuthorizationResultCode)getReplicantRepresentation:(NSDictionary **)rep
                                    forReplicationOffset:(NSInteger )offset
                                                database:(MCPGDatabase *)db;


/*!
 Gets all the replicants for a given user and type
 */
+ (MCSAuthorizationResultCode)getAllReplicantRepresentations:(NSArray **)reps
                                               ofReplicaType:(MCSReplicaType)type
                                              withDeviceName:(NSString *)deviceName
                                       forUserRepresentation:(NSDictionary *)userRep
                                                    database:(MCPGDatabase *)db;



/*!
 Figures out whether the stage or replicant has been wiped or has to be reset. Returns kMCSAuthorizationResultSuccess if all is good. Expects all arguments.
 */
+ (MCSReplicaStatus)getResponseCodeForReplicantRepresentation:(NSDictionary *)replicantRep
                                           userRepresentation:(NSDictionary *)userRep
                                                     database:(MCPGDatabase *)db;


/*!
 Adds the auth session id if one is required.
 */
+ (MCSAuthorizationResultCode)stuffAdditionalAuthorizationValidation:(NSDictionary *)payload
                                                        intoResponse:(NSMutableDictionary *)response
                                                  userRepresentation:(NSDictionary *)userRep
                                                            database:(MCPGDatabase *)db;

/*!
 Adds optimization data if possible. For example if the client is sending last sync date we can return the pending change count to prevent an unnecessary sync thus reducing server overhead.
 */
+ (MCSAuthorizationResultCode)addOptimizationDataIfPossibleForValidation:(NSDictionary *)payload
                                                            intoResponse:(NSMutableDictionary *)response
                                                              clientUUID:(NSString *)aUUID
                                                      userRepresentation:(NSDictionary *)userRep
                                                                database:(MCPGDatabase *)db;


/*!
 Given a override file, returns a response with either debug info and code or service down info and code. The path to the override file is usually a launch argument.
 */
+ (NSMutableDictionary *)responseForOverrideInFile:(NSString *)overridePath
                              authorizationRequest:(NSDictionary *)payload;

/*!
 If the service is down, build up the authorization response that we need, so the client side can handles it gracefully.
 */
+ (NSMutableDictionary *)responseForServiceDownDetails:(NSDictionary *)details
                                  authorizationRequest:(NSDictionary *)payload;

/*!
 Use to debug how the client behaves with different response codes. See BPAdminDefines.h.
 */
+ (NSMutableDictionary *)responseForDebugDetails:(NSDictionary *)details
                            authorizationRequest:(NSDictionary *)payload;


/*!
 We don't want to log out the password.
 */
+ (NSDictionary *)requestWithoutPassword:(NSDictionary *)request;


/*!
 Builds up the entire response for the authorization request.
 */
+ (NSMutableDictionary *)responseForCloudAuthorizationRequest:(NSDictionary *)payload
                                          optionalHostingNode:(MCHostingNode *)node
                                        optionalHostingServer:(MCHostedServer *)hostedServer;

@end
