//
//  ASWSelfHealer.h
//  ASWFoundation
//
//  Created by Mike Blaguszewski on 5/9/08.
//  Copyright 2008 Ambrosia Software, Inc.. All rights reserved.
//

#import <Cocoa/Cocoa.h>

/*! \file ASWSelfHealer.h
	\brief Low level interface for application self-healing */
	
/*! Result code returned from self-healing operations */
typedef enum
{
	/*! Had to heal, but encountered no errors doing so. Note that if multiple
	    problems are found, not all of them can be fixed at one time, but this
		code may still be returned. */
	ASWSelfHealingSucceeded,
	/*! Found unfixable problems, or tried to heal and failed */
	ASWSelfHealingFailed,
	/*! Asked user if they wanted to self-heal, and they refused */
	ASWSelfHealingCanceled,
	/*! No problems found, so nothing to do */
	ASWSelfHealingUnnecessary
} ASWSelfHealingResult;

@class ASWSelfHealer;

@protocol ASWSelfHealerDelegate
/*! \brief Return TRUE if this component should be included in validation */
- (BOOL) selfHealer: (ASWSelfHealer*) healer shouldValidateComponent: (NSString*) component componentIsExternal: (BOOL) external;
@end

/*! \brief Class for managing ability to repair an application's support files
	\ingroup ASWAppKit
 
	Uses a signed plist of file metadata to check the integrity of key application
	components, such as external dependencies or executables requiring special
	permissions. If problems are found, allows recovery by fixing file permissions
	or running an installer to update external components. */
@interface ASWSelfHealer : NSObject
{
	NSBundle *_bundle;
	NSArray *_internalFiles;
	NSArray *_externalFiles;
	
	id<ASWSelfHealerDelegate> delegate;
}
@property (assign) id<ASWSelfHealerDelegate> delegate;

/*! \brief designated initializer
	\param path A plist created with make-self-healing-plist.rb describing important 
	component files and their necessary permissions.
	\param signedHash An SHA1 hash of the plist file, signed with Ambrosia code-signing key
	\param bundle The bundle used to find internal components. Defaults to the main bundle.
	\return An initialized self-healer or nil, if the plist or signature are invalid */
- (id)initWithPlist:(NSString *)path signature:(NSData *)signedHash bundle:(NSBundle *)bundle;
/*! \brief Are all external components valid?
	\param requiresReinstall Required. On return, value indicates whether an internal
	 component is corrupted beyond repair, requiring a reinstall of the software. Currently,
	 this means that the file was missing, or the contents didn't match the stored hash.
	 \return Whether all internal components were found to be valid */
- (BOOL)validateInternalComponents:(BOOL *)requiresReinstall;
/*! \brief Are all external components valid? */
- (BOOL)validateExternalComponents;
/*! \brief Attempt fix any errors in internal or external files
	Calls the internal validation functions and tries to fix any problems found. Will fail
	a WindowServer connection is not available or the user fails to authenticate. If
	multiple external components are found to be broken, we only launch an installer
	for the first one we find. */
- (ASWSelfHealingResult)healIfNecessary;

/*! \brief Attempt to uninstall any external files
	Iterates through all installed files read in from the manifest plist, and attempts
	to remove them. If root access is required, a root shell will be created and used for
	files which cannot be removed by the user.
	\return ASWSelfHealingSucceeded if the files were uninstalled,
			ASWSelfHealingFailed if the files could not be removed,
			ASWSelfHealiungUnnecessary if the files are not installed
 */
- (ASWSelfHealingResult)uninstallIfNecessary;

- (NSArray*) externalComponentsWithProblems;

/*! \brief Returns an array of files which are installed
 */
- (NSArray *)installedExternalFiles;
@end
