//
//  GUIFileHandler.m
//  CyTV
//
//  Created by Andreas Junghans on 03.01.08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "GUIFileHandler.h"
#import "HTTPServer.h"

// TODO: support caching


@implementation GUIFileHandler

+ (void)writeFileForPath:(NSString *)filePath contentType:(NSString *)contentType socket:(AsyncSocket *)socket {
    NSString *guiPath = [[NSBundle mainBundle] pathForResource:@"Client GUI" ofType:@""];
    NSString *completePath = [[guiPath stringByAppendingString:filePath] stringByStandardizingPath];
    
    // check for invalid paths (e.g. when ".." is used in the path specified in the URL)
    if (![completePath hasPrefix:guiPath]) {
        [ResponseHandler writeResponseWithCode:404 content:@"Not found" socket:socket timeout:WRITE_ERROR_TIMEOUT];
        return;
    }
    
    // load the resource
    NSData *resourceData = [NSData dataWithContentsOfFile:completePath];
    if (resourceData == nil) {
        [ResponseHandler writeResponseWithCode:404 content:@"Not found" socket:socket timeout:WRITE_ERROR_TIMEOUT];
        return;
    }
    
    // write the response
    CFHTTPMessageRef response = CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1);
    unsigned long long contentLength = [resourceData length];
    NSString *contentLengthString = [[NSNumber numberWithUnsignedLongLong:contentLength] stringValue];
    CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Length"), (CFStringRef)contentLengthString);
    if (contentType != nil) {
        CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Type"), (CFStringRef)contentType);
    }
    NSData *responseData = [(NSData *)CFHTTPMessageCopySerializedMessage(response) autorelease];
    [socket writeData:responseData withTimeout:WRITE_BODY_TIMEOUT tag:HTTP_PARTIAL_RESPONSE];
    [socket writeData:resourceData withTimeout:WRITE_BODY_TIMEOUT tag:HTTP_RESPONSE];
}

- (void)handleRequest {
    NSString *filePath = [_path substringFromIndex:4];   // remove "/gui"
    [[self class] writeFileForPath:filePath contentType:nil socket:_asyncSocket];
}

@end
