//
//  FolderDetailViewController.m
//  pithos-ios
//
// Copyright 2011-2013 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 "FolderDetailViewController.h"
#import "EditMetadataViewController.h"
#import "EditPermissionsViewController.h"
#import "OpenStackAccount.h"
#import "Container.h"
#import "Folder.h"
#import "StorageObject.h"
#import "ActivityIndicatorView.h"
#import "APICallback.h"
#import "AccountManager.h"
#import "UIViewController+Conveniences.h"
#import "NSString+Conveniences.h"

#define kOverview 0
#define kMetadata 1
#define kPermissions 2

#define maxMetadataViewableLength 12

@implementation FolderDetailViewController

@synthesize account, container, folder, folderViewController, permissions;

#pragma mark - View lifecycle

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.permissions = [folder.folderObject permissions];
    folderIsReadOnly = NO;
    if (account.sharingAccount && permissions.count) {
        folderIsReadOnly = ![[permissions objectForKey:account.username] isEqualToString:@"write"];
    }
    
    object = [[StorageObject alloc] init];
    object.name = folder.name;
    object.metadata = folder.metadata;
    object.fullPath = [folder fullPath];
    object.sharing = folder.sharing;
    object.contentType = folder.contentType;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.tableView reloadData];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (folder.metadata == nil) {
        [self reloadMetadataSection];
    } else {
        [self updatePermissionsUserCatalog];
    }
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    folder.sharing = object.sharing;
}

#pragma mark - Memory management

- (void)dealloc {
    [object release];
    [account release];
    [container release];
    [folderViewController release];
    [folder release];
    [permissions release];
    [super dealloc];
}

#pragma mark - Internal

- (void)updatePermissionsUserCatalog {
    NSMutableArray *UUIDs = [NSMutableArray arrayWithCapacity:permissions.count];
    for (NSString *user in [permissions allKeys]) {
        NSRange rangeOfColumn = [user rangeOfString:@":"];
        NSString *UUID = (rangeOfColumn.location == NSNotFound) ? user : [user substringToIndex:rangeOfColumn.location];
        if (![UUID isEqualToString:@"*"]) {
            [UUIDs addObject:UUID];
        }
    }
    if (UUIDs.count) {
        __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Loading permissions..."
                                                                                                       andAddToView:self.view];
        [[self.account.manager userCatalogForDisplaynames:nil UUIDs:UUIDs]
         success:^(OpenStackRequest *request) {
             [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
             [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:kPermissions] withRowAnimation:UITableViewRowAnimationNone];
         }
         failure:^(OpenStackRequest *request) {
             [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
         }];
    }
}
#pragma mark - Actions

- (void)reloadMetadataSection {
    __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Loading metadata..."
                                                                                                   andAddToView:self.view];
    [[self.account.manager getObjectInfo:container object:object version:nil]
     success:^(OpenStackRequest *request) {
         [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
         folder.metadata = [NSMutableDictionary dictionary];
         for (NSString *header in request.responseHeaders) {
             NSString *metadataKey;
             NSString *metadataValue;
             if ([header rangeOfString:@"X-Object-Meta-"].location != NSNotFound) {
                 metadataKey = [NSString decodeFromPercentEscape:[header substringFromIndex:14]];
                 metadataValue = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:header]];
                 [folder.metadata setObject:metadataValue forKey:metadataKey];
             }
         }
         object.metadata = folder.metadata;
         [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:kMetadata] withRowAnimation:UITableViewRowAnimationFade];
         [self updatePermissionsUserCatalog];
     }
     failure:^(OpenStackRequest *request) {
         [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
         [self alert:@"There was a problem retrieving the object's metadata." request:request];
     }];
}

#pragma mark - UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section == kOverview) {
        return (folder.lastModifiedString ? 3 : 2);
    } else if (section == kPermissions) {
        if (account.sharingAccount) {
            return permissions.count;
        } else {
            return (permissions.count + 1);
        }
    } else if (section == kMetadata) {
        if (folderIsReadOnly) {
            return [folder.metadata count];
        } else {
            return ([folder.metadata count] + 1);
        }
    }
    return 0;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat result = tableView.rowHeight;
    if ((indexPath.section == kOverview) && ((indexPath.row == 0) || (indexPath.row == 1))) {
        NSString *text;
        if (indexPath.row == 0) {
            text = folder.name;
        } else {
            text = folder.fullPath;
            if ([text hasPrefix:@"/"]) {
                text = [text substringFromIndex:1];
            }
        }
        result = 22.0 + [text sizeWithFont:[UIFont systemFontOfSize:18.0]
                         constrainedToSize:(([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) ?
                                            CGSizeMake(537.0, 9000.0) :
                                            CGSizeMake(221.0, 9000.0))
                             lineBreakMode:UILineBreakModeCharacterWrap].height;
    }
    return MAX(tableView.rowHeight, result);
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];

        cell.textLabel.backgroundColor = [UIColor clearColor];
        cell.detailTextLabel.backgroundColor = [UIColor clearColor];
        cell.detailTextLabel.numberOfLines = 0;
        cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
        cell.detailTextLabel.textAlignment = UITextAlignmentRight;
    }
    
    if (indexPath.section == kOverview) {
        cell.accessoryType = UITableViewCellAccessoryNone;
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.accessoryView = nil;
        if (indexPath.row == 0) {
            cell.textLabel.text = @"Name";
            cell.detailTextLabel.text = folder.name;
        } else if (indexPath.row == 1) {
            cell.textLabel.text = @"Full Path";
            NSString *folderFullPathToShow = folder.fullPath;
            if ([folderFullPathToShow hasPrefix:@"/"]) {
                folderFullPathToShow = [folderFullPathToShow substringFromIndex:1];
            }
            cell.detailTextLabel.text = folderFullPathToShow;
        } else if (indexPath.row == 2) {
            cell.textLabel.text = @"Last Modified";
            cell.detailTextLabel.text = folder.lastModifiedString;
        }
    } else if (indexPath.section == kMetadata) {
        if (folderIsReadOnly) {
            cell.accessoryType = UITableViewCellAccessoryNone;
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            cell.userInteractionEnabled = NO;
        }
        else {
            cell.selectionStyle = UITableViewCellSelectionStyleBlue;
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
        cell.accessoryView = nil;
        if (indexPath.row == [folder.metadata count]) {
            cell.textLabel.text = @"Add Metadata";
            cell.detailTextLabel.text = @"";
        } else {
            NSString *key = [[folder.metadata allKeys] objectAtIndex:indexPath.row];
            NSString *value = [folder.metadata objectForKey:key];
            NSString *metadataKeyCellText = key;
            NSString *metadataValueCellText = value;
            if ([metadataKeyCellText length] > maxMetadataViewableLength) {
                metadataKeyCellText = [metadataKeyCellText substringToIndex:(maxMetadataViewableLength - 3)];
                metadataKeyCellText = [metadataKeyCellText stringByAppendingString:@"..."];
            }
            if ([metadataValueCellText length] > maxMetadataViewableLength) {
                metadataValueCellText = [metadataValueCellText substringToIndex:(maxMetadataViewableLength - 3)];
                metadataValueCellText = [metadataValueCellText stringByAppendingString:@"..."];
            }

            cell.textLabel.text = metadataKeyCellText;
            cell.detailTextLabel.text = metadataValueCellText;
        }
    } else if (indexPath.section == kPermissions) {
        if (account.sharingAccount) {
            cell.accessoryType = UITableViewCellAccessoryNone;
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            cell.userInteractionEnabled = NO;
        } else {
            cell.selectionStyle = UITableViewCellSelectionStyleBlue;
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
        cell.accessoryView = nil;
        
        if (indexPath.row == permissions.count) {
            cell.textLabel.text = @"Share";
            cell.detailTextLabel.text = @""; 
        } else {
            NSString *user = [[[permissions allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] objectAtIndex:indexPath.row];
            NSRange rangeOfColumn = [user rangeOfString:@":"];
            NSString *UUID = (rangeOfColumn.location == NSNotFound) ? user : [user substringToIndex:rangeOfColumn.location];
            NSString *group = ((rangeOfColumn.location == NSNotFound) || (rangeOfColumn.location == user.length - 1)) ? nil : [user substringFromIndex:(rangeOfColumn.location + 1)];
            NSMutableString *displayname = [NSMutableString stringWithString:[account displaynameForUUID:UUID safe:YES]];
            if (group) {
                [displayname appendFormat:@":%@", group];
            }
            cell.textLabel.text = displayname;
            
            cell.detailTextLabel.numberOfLines = 1;
            cell.detailTextLabel.lineBreakMode = UILineBreakModeTailTruncation;
            cell.detailTextLabel.text = ([[permissions objectForKey:user] isEqualToString:@"write"] ? @"Read/Write" : @"Read Only");
        }
    }

    return cell;
}

#pragma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == kMetadata) {
        EditMetadataViewController *vc = [[EditMetadataViewController alloc] initWithNibName:@"EditMetadataViewController" bundle:nil];
        NSString *metadataKey;
        NSString *metadataValue;
        
        if (indexPath.row == [self.folder.metadata count]) {
            metadataKey = @"";
            metadataValue = @"";
            vc.removeMetadataEnabled = FALSE;
            vc.navigationItem.title = @"Add Metadata";
        } else {
            metadataKey = [[self.folder.metadata allKeys] objectAtIndex:indexPath.row];
            metadataValue = [self.folder.metadata objectForKey:metadataKey];
            vc.removeMetadataEnabled = TRUE;
            vc.navigationItem.title = @"Edit Metadata";
        }
                
        vc.metadataKey = metadataKey;
        vc.metadataValue = metadataValue;
        vc.account = account;
        vc.container = container;
        vc.object = object;
        vc.objectIsFolder = YES;
        vc.folderViewController = folderViewController;

        [self.navigationController pushViewController:vc animated:YES];
        [vc release];
    } else if (indexPath.section == kPermissions) {
        EditPermissionsViewController *vc = [[EditPermissionsViewController alloc] initWithNibName:@"EditPermissionsViewController" bundle:nil];
        NSString *user;
        
        if (indexPath.row == permissions.count) {
            user = @"";
            vc.removePermissionsEnabled = NO;
            vc.navigationItem.title = @"Add Permission";
        } else {
            user = [[[permissions allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] objectAtIndex:indexPath.row];
            NSString *userPermissions = [permissions objectForKey:user];
            if ([userPermissions rangeOfString:@"read"].location != NSNotFound) {
                vc.readPermissionSelected = YES;
            } else {
                vc.readPermissionSelected = NO;
            }
            if ([userPermissions rangeOfString:@"write"].location != NSNotFound) {
                vc.writePermissionSelected = YES;
            } else {
                vc.writePermissionSelected = NO;
            }
            vc.removePermissionsEnabled = YES;
            vc.navigationItem.title = @"Edit Permission";
        }
        
        vc.permissionUser = user;
        vc.permissions = permissions;
        vc.account = account;
        vc.container = container;
        vc.object = object;
        vc.objectIsFolder = YES;
        vc.folderViewController = folderViewController;
        [self.navigationController pushViewController:vc animated:YES];
        [vc release];
    } 
}

@end
