//
//  MCDaemonKeeper.h
//  MCClientServer
//
//  Created by Brent Gulanowski on 10-02-08.
//  Copyright 2010 Marketcircle Inc. All rights reserved.
//


#import <MCClientServer/MCConfigDOServerProtocol.h>

#import <Foundation/Foundation.h>


enum {
	kMCClientAgentModelStandard, // copy the plist, keep the daemon in the bundle
	kMCClientAgentModelSymlinkJobPlist, // symlink the plist, keep the daemon in the bundle
	kMCClientAgentModelCopyToolToHelperFolder // copy the plist, copy the daemon from the bundle into the helper tools folder
};

@class SFAuthorization;
@class MCConfigClientEndpoint;

@interface MCDaemonKeeper : NSObject {

	SFAuthorization *auth;

	MCConfigClientEndpoint *configEndpoint;
	
	NSConnection*                    doConnection;
	id <MCConfigDOServerProtocol>    configProxy;
	
	id connectionDelegate;
	
	NSUInteger clientAgentModel;
#if 1
	NSString * serverUUID;
#endif
}

#if 1
@property (nonatomic, retain) NSString * serverUUID;
#endif

@property (retain) SFAuthorization *auth;
//  if this property is set, we are connected to the configd DO server
@property (retain, readonly) id <MCConfigDOServerProtocol> configProxy;
@property (readwrite) NSUInteger clientAgentModel;

- (BOOL)authorize;

- (BOOL)checkServerBundlePermissions;
- (BOOL)checkServerEnvironment:(NSString **)errorString;
- (BOOL)repairPermissions:(NSError **)error;

- (NSDictionary *)propertyListForJobName:(NSString *)jobName daemon:(BOOL)flag;
- (BOOL)toggleServerDaemons:(NSArray *)jobLabels on:(BOOL)flag error:(NSError **)perror failedJobName:(NSString **)failedJobName;

- (void)connectToConfig:(id)opDelegate;
- (void)stopConfig;

- (BOOL)isPostgresInitialized;
- (BOOL)isPostgresRunning;

- (BOOL)initPostgres:(NSError **)error;
- (BOOL)startPostgres:(NSError **)error;
- (BOOL)stopPostgres:(NSError **)error;

// TODO: deal with these
- (BOOL)startPostgresWithOptions:(NSArray*)options error:(NSError **)error;
- (BOOL)restartPostgresWithOptions:(NSArray *)options error:(NSError **)error;

//FSync setting
- (BOOL)enableFSyncWritethroughAndReturnError: (NSError**)error;
- (BOOL)disableFSyncWritethroughAndReturnError: (NSError**)error;

// Time Machine Exclusion
- (BOOL)excludeDataPathFromTimeMachine: (NSError**)error;

// Cloud Keychain accessors
- (BOOL)saveCloudPassword:(NSString *)password forUsername:(NSString *)username;
- (NSString *)cloudPasswordForUsername:(NSString *)username;

- (BOOL)serverOn;
- (BOOL)turnServerOn:(NSError **)error;
- (BOOL)turnServerOff:(NSError **)error;
- (BOOL)turnServerOff:(NSError **)error leavingPostgresRunning:(BOOL)leavePostgres;

// Call when the automatic backup schedule is changed
- (BOOL)refreshBackup:(NSError **)error;

// Touch Server On/Off
- (BOOL)turnTouchServerOn:(NSError **)error;
- (BOOL)turnTouchServerOff:(NSError **)error;

// Touch Server Status
- (BOOL)touchServerOn;

//Touch Stage
- (void)verifyClientStageRebuild:(NSString *)clientID;
- (BOOL)deleteClientStageDirectory:(NSString *)directory;

- (BOOL)loadClientAgents:(NSError **)error;
- (BOOL)unloadClientAgents:(NSError **)error;

- (BOOL)unloadMirrorDaemon:(NSError **)anError;

// Subclasses should call this in +initialize for the benefit of the background utilities trying to find the auth ctl tool
+ (void)setServerDaemonKeeperClass:(Class)aClass;

// Subclass methods
+ (NSBundle *)serverBundle;
+ (NSString *)backupdJobName; // Used to treat the backupd property list specially when loading
+ (NSString *)configdJobName;
+ (NSString *)touchdJobName;
+ (NSString *)stagedJobName;
+ (NSString *)mirrordJobName;
+ (UInt16)configdKickPort;
+ (NSString *)serverUserName; // also used as group name

- (void)didConnectToConfig:(BOOL)connected;
// active jobs are those which should be (un)loaded as part of (dis|en)abling the server; names as in plists (must match plist names)
- (NSArray *)activeServerLaunchJobNames;
- (NSArray *)activeClientLaunchJobNames;

@end

@interface NSObject (MCDaemonKeeperConnectionDelegate)

- (void)daemonKeeperConfigConnected:(MCDaemonKeeper *)serverInstaller;
- (void)daemonKeeper:(MCDaemonKeeper *)serverInstaller configNotConnected:(NSError *)error;

@end
