//
//  EditPermissionsViewController.m
//  pithos-ios
//
// Copyright 2011 GRNET S.A. All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
// 
//   1. Redistributions of source code must retain the above
//      copyright notice, this list of conditions and the following
//      disclaimer.
// 
//   2. Redistributions in binary form must reproduce the above
//      copyright notice, this list of conditions and the following
//      disclaimer in the documentation and/or other materials
//      provided with the distribution.
// 
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// 
// The views and conclusions contained in the software and
// documentation are those of the authors and should not be
// interpreted as representing official policies, either expressed
// or implied, of GRNET S.A.

#import "EditPermissionsViewController.h"
#import "AccountManager.h"
#import "UIViewController+Conveniences.h"
#import "FolderViewController.h"
#import "Folder.h"
#import "PithosUtilities.h"
#import "APICallback.h"

#define kUser 0
#define kPermissions 1
#define kSavePermissions 2
#define kRemovePermissions 3

@implementation EditPermissionsViewController

@synthesize account, container, object;
@synthesize user, readPermissionSelected, writePermissionSelected, permissions;
@synthesize oldPermissionsString;
@synthesize newPermissionsEntry, removePermissionsEnabled;
@synthesize folderViewController, objectIsFolder;

- (void)dealloc
{
    [account release];
    [container release];
    [object release];
    [user release];
    [permissions release];
    [oldPermissionsString release];
    [activityIndicatorView release];
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    if (removePermissionsEnabled)
        return 4;
    else 
        return 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == kPermissions)
        return 2;
    else
        return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    
    if (indexPath.section == kUser) {
        UITextField *textField = nil;
        for (id subView in cell.contentView.subviews) {
            if ([subView isKindOfClass:[UITextField class]]) {
                textField = (UITextField *)subView;
            }
        }
        
        if (textField == nil) {
            CGRect bounds = [cell.contentView bounds];
            CGRect rect = CGRectInset(bounds, 10.0, 10.0);                        
            textField = [[UITextField alloc] initWithFrame:rect];
            [textField setFrame:rect];
        }
        
        [textField setClearButtonMode:UITextFieldViewModeWhileEditing];
        [textField setBackgroundColor:[UIColor clearColor]];
        [textField setOpaque:YES];
        [textField setAutocorrectionType:UITextAutocorrectionTypeNo];
        [textField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
        [textField setDelegate:self];
        textField.placeholder = @"User or User:Group";
        textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        textField.text = self.user;
        
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        [cell.contentView addSubview:textField];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    else if (indexPath.section == kPermissions) {
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        if (indexPath.row == 0) {
            cell.textLabel.text = @"Read Only";
            if (readPermissionSelected)
                cell.accessoryType = UITableViewCellAccessoryCheckmark;
            else
                cell.accessoryType = UITableViewCellAccessoryNone;
        }
        else {
            cell.textLabel.text = @"Read/Write";
            if (writePermissionSelected)
                cell.accessoryType = UITableViewCellAccessoryCheckmark;
            else
                cell.accessoryType = UITableViewCellAccessoryNone;
        }
    } 
    else if (indexPath.section == kSavePermissions) {
        cell.textLabel.text = @"Save";
        cell.accessoryType = UITableViewCellAccessoryNone;
        cell.selectionStyle = UITableViewCellSelectionStyleBlue;
    }
    else if (indexPath.section == kRemovePermissions) {
        cell.textLabel.text = @"Remove";
        cell.accessoryType = UITableViewCellAccessoryNone;
        cell.selectionStyle = UITableViewCellSelectionStyleBlue;
    }
    
    return cell;
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{    
    
    if (indexPath.section != kUser)
        [self.view endEditing:YES];
    
    NSString *newUserName;
    NSIndexPath *userCellIndexPath = [NSIndexPath indexPathForRow:0 inSection:kUser];
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:userCellIndexPath];
    UITextField *textField = [[cell.contentView subviews] objectAtIndex:0];
    newUserName = textField.text;
    if (![self userInputIsValid:newUserName]) {
        [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
        return;
    }
    
    if (indexPath.section == kPermissions) {
        UITableViewCell *readPermissionsCell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:kPermissions]];
        UITableViewCell *writePermissionsCell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:kPermissions]];

        if (indexPath.row == 0) {
            if (!readPermissionSelected) {
                readPermissionSelected = YES;
                if (writePermissionSelected) {
                    writePermissionSelected = FALSE;
                    writePermissionsCell.accessoryType = UITableViewCellAccessoryNone;
                }
                readPermissionsCell.accessoryType = UITableViewCellAccessoryCheckmark;
            }
        }
        else if (indexPath.row == 1) {
            if (!writePermissionSelected) {
                writePermissionSelected = YES;
                if (readPermissionSelected) {
                    readPermissionSelected = FALSE;
                    readPermissionsCell.accessoryType = UITableViewCellAccessoryNone;
                }
                writePermissionsCell.accessoryType = UITableViewCellAccessoryCheckmark;
            }
        }
    }
    else if (indexPath.section == kSavePermissions) {
        if (!readPermissionSelected && !writePermissionSelected) {
            [self alert:@"Cannot save permissions"  message:@"Please select permissions type"];
            [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
            return;
        }
        
        [self.permissions removeObjectForKey:self.user];
        if (readPermissionSelected) 
            [self.permissions setObject:@"read" forKey:newUserName];
        else if (writePermissionSelected)
            [self.permissions setObject:@"write" forKey:newUserName];
        
        self.user = newUserName;
        self.oldPermissionsString = object.sharing;
        object.sharing = [self buildPermissionsString];
        
        if (objectIsFolder && ![PithosUtilities isContentTypeDirectory:object.contentType]) {
            if (((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) &&
                [folderViewController.parentFolderViewController.folder.objects objectForKey:object.name]) || 
                ((UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) &&
                 [folderViewController.folder.objects objectForKey:object.name])) {
                NSString *alertMessage = [NSString stringWithFormat:@"In order to apply the changes in '%@', the object at the same path must be replaced. Continue?",object.name];
                NSString *alertTitle = @"Apply changes";
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertTitle
                                                                message:alertMessage
                                                               delegate:self
                                                      cancelButtonTitle:@"Cancel"
                                                      otherButtonTitles:@"OK", nil];
                [alert show];
                [alert release];
                return;
            } else {
                NSString *activityMessage = @"Applying permissions...";
                [activityIndicatorView release];
                activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
                [activityIndicatorView addToView:self.view];
                
                object.name = object.fullPath;
                object.contentType = @"application/directory";
                object.data = [NSData data];
                [self createNewFolder];  
                return;
            }
        }
        
        NSString *activityMessage = @"Applying permissions...";
        [activityIndicatorView release];
        activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
        
        [activityIndicatorView addToView:self.view];
        [[self.account.manager writeObjectMetadata:container object:object] 
         success:^(OpenStackRequest *request) {
             [activityIndicatorView removeFromSuperview];
             [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
             removePermissionsEnabled = YES;
             [self.tableView reloadData];
             if (objectIsFolder || (account.shared && ![oldPermissionsString isEqualToString:object.sharing])) {
                 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
                     [self.folderViewController refreshButtonPressed:nil];
                 }
                 else {
                     self.folderViewController.needsRefreshing = YES;
                 }
             } 
         }
         failure:^(OpenStackRequest *request) {
             object.sharing = self.oldPermissionsString;
             readPermissionSelected = !readPermissionSelected;
             writePermissionSelected = !writePermissionSelected;
             
             if (readPermissionSelected)
                 [self.permissions setObject:@"read" forKey:user];
             else if (writePermissionSelected) 
                 [self.permissions setObject:@"write" forKey:user];
             
             [activityIndicatorView removeFromSuperview];
             [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
             [self.tableView reloadData];
             [self alert:@"There was a problem applying the permissions." request:request];
         }];
    } 
    else if (indexPath.section == kRemovePermissions) {
        NSString *activityMessage = @"Removing permissions...";   
        [activityIndicatorView release];
        activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
        [activityIndicatorView addToView:self.view];
        
        [permissions removeObjectForKey:user];
        self.oldPermissionsString = object.sharing;
        object.sharing = [self buildPermissionsString];
        [[self.account.manager writeObjectMetadata:container object:object] 
         success:^(OpenStackRequest *request) {
             self.user = @"";
             self.readPermissionSelected = FALSE;
             self.writePermissionSelected = FALSE;
             removePermissionsEnabled = NO;
             [self.tableView reloadData];
             [activityIndicatorView removeFromSuperview];
             [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
             if (objectIsFolder || (account.shared && ![oldPermissionsString isEqualToString:object.sharing])) {
                 self.folderViewController.needsRefreshing = YES;
                 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
                     [self.folderViewController refreshButtonPressed:nil];
                 else
                     self.folderViewController.refreshWhenAppeared = YES;
             }
         }
         failure:^(OpenStackRequest *request) {
             object.sharing = self.oldPermissionsString;
             if (readPermissionSelected)
                 [self.permissions setObject:@"read" forKey:user];
             else if (writePermissionSelected) 
                 [self.permissions setObject:@"write" forKey:user];
             
             [activityIndicatorView removeFromSuperview];
             [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
             [self.tableView reloadData];
             [self alert:@"There was a problem removing the permissions." request:request];
         }];
    }
}

#pragma mark - Textfield delegate


- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [self userInputIsValid:textField.text];
    [textField resignFirstResponder];
    
    return YES;
}

#pragma mark - Alertview delegate

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        NSString *activityMessage = @"Applying permissions...";
        [activityIndicatorView release];
        activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
        [activityIndicatorView addToView:self.view];
        
        object.name = object.fullPath;
        object.contentType = @"application/directory";
        object.data = [NSData data];
        [self createNewFolder];
    } else {
        [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
    }
}

- (void)createNewFolder {
    [[self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil]
     success:^(OpenStackRequest *request) {
         Folder *newFolder = [[Folder alloc] init];
         newFolder.name = [[object.name componentsSeparatedByString:@"/"] lastObject];
         newFolder.parent = folderViewController.folder;
         newFolder.sharing = folderViewController.folder.sharing;
         [folderViewController.folder.folders setObject:newFolder forKey:newFolder.name];
         [activityIndicatorView removeFromSuperview];
         [newFolder release];
         [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
         removePermissionsEnabled = YES;
         [self.tableView reloadData];
         if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
             [self.folderViewController refreshButtonPressed:nil];
         }
         else {
             self.folderViewController.needsRefreshing = YES;
             self.folderViewController.refreshWhenAppeared = YES;
         }            
     }
     failure:^(OpenStackRequest *request) {
         object.sharing = self.oldPermissionsString;
         readPermissionSelected = !readPermissionSelected;
         writePermissionSelected = !writePermissionSelected;
         
         if (readPermissionSelected)
             [self.permissions setObject:@"read" forKey:user];
         else if (writePermissionSelected) 
             [self.permissions setObject:@"write" forKey:user];
         
         [activityIndicatorView removeFromSuperview];
         [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
         [self.tableView reloadData];
         [self alert:@"There was a problem applying the permissions." request:request];                                    
     }];
}

#pragma mark - helper methods

- (NSString *)buildPermissionsString
{
    NSString *readPermissionsString = @"";
    NSString *writePermissionsString = @"";
    
    for (NSString *aUser in [permissions allKeys]) {
        if ([[permissions objectForKey:aUser] isEqual:@"read"]) {
            if ([readPermissionsString length] == 0)
                readPermissionsString = [NSString stringWithFormat:@"read=%@", aUser];
            else
                readPermissionsString = [NSString stringWithFormat:@"%@,%@", readPermissionsString ,aUser];
        }
        else if ([[permissions objectForKey:aUser] isEqual:@"write"]) {
            if ([writePermissionsString length] == 0)
                writePermissionsString = [NSString stringWithFormat:@"write=%@", aUser];
            else
                writePermissionsString = [NSString stringWithFormat:@"%@,%@", writePermissionsString, aUser];
        }
    }
    
    if ([writePermissionsString length] == 0)
        return readPermissionsString;
    else if ([readPermissionsString length] == 0)
        return writePermissionsString;
    else return [NSString stringWithFormat:@"%@;%@", readPermissionsString, writePermissionsString];
}

- (BOOL) userInputIsValid: (NSString *) input
{
    if ([input length] == 0
        || [[input stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0
        ) {
        [self alert:@"Invalid input" message:@"User name cannot be empty"];
        return NO;
    }
    else {
        NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"=,;"];
        if ([input rangeOfCharacterFromSet:set].location != NSNotFound) {
            [self alert:@"Invalid input" message:@"User name cannot contain '=', ',' or ';'"];
            return NO;
        }
        else {
            return YES;
        }
    }
    
    return YES;
}


@end
