/*
 Copyright (c) 2012-2015, Pierre-Olivier Latour
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright
 notice, this list of conditions and the following disclaimer.
 * 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.
 * The name of Pierre-Olivier Latour may not be used to endorse
 or promote products derived from this software without specific
 prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 PIERRE-OLIVIER LATOUR 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.
 */

#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif

#import "GCDWebServerPrivate.h"

#define kMultiPartBufferSize (256 * 1024)

typedef enum {
  kParserState_Undefined = 0,
  kParserState_Start,
  kParserState_Headers,
  kParserState_Content,
  kParserState_End
} ParserState;

@interface GCDWebServerMIMEStreamParser : NSObject
- (id)initWithBoundary:(NSString*)boundary defaultControlName:(NSString*)name arguments:(NSMutableArray*)arguments files:(NSMutableArray*)files;
- (BOOL)appendBytes:(const void*)bytes length:(NSUInteger)length;
- (BOOL)isAtEnd;
@end

static NSData* _newlineData = nil;
static NSData* _newlinesData = nil;
static NSData* _dashNewlineData = nil;

@interface GCDWebServerMultiPart () {
@private
  NSString* _controlName;
  NSString* _contentType;
  NSString* _mimeType;
}
@end

@implementation GCDWebServerMultiPart

@synthesize controlName=_controlName, contentType=_contentType, mimeType=_mimeType;

- (id)initWithControlName:(NSString*)name contentType:(NSString*)type {
  if ((self = [super init])) {
    _controlName = [name copy];
    _contentType = [type copy];
    _mimeType = GCDWebServerTruncateHeaderValue(_contentType);
  }
  return self;
}

@end

@interface GCDWebServerMultiPartArgument () {
@private
  NSData* _data;
  NSString* _string;
}
@end

@implementation GCDWebServerMultiPartArgument

@synthesize data=_data, string=_string;

- (id)initWithControlName:(NSString*)name contentType:(NSString*)type data:(NSData*)data {
  if ((self = [super initWithControlName:name contentType:type])) {
    _data = data;
    
    if ([self.contentType hasPrefix:@"text/"]) {
      NSString* charset = GCDWebServerExtractHeaderValueParameter(self.contentType, @"charset");
      _string = [[NSString alloc] initWithData:_data encoding:GCDWebServerStringEncodingFromCharset(charset)];
    }
  }
  return self;
}

- (NSString*)description {
  return [NSString stringWithFormat:@"<%@ | '%@' | %lu bytes>", [self class], self.mimeType, (unsigned long)_data.length];
}

@end

@interface GCDWebServerMultiPartFile () {
@private
  NSString* _fileName;
  NSString* _temporaryPath;
}
@end

@implementation GCDWebServerMultiPartFile

@synthesize fileName=_fileName, temporaryPath=_temporaryPath;

- (id)initWithControlName:(NSString*)name contentType:(NSString*)type fileName:(NSString*)fileName temporaryPath:(NSString*)temporaryPath {
  if ((self = [super initWithControlName:name contentType:type])) {
    _fileName = [fileName copy];
    _temporaryPath = [temporaryPath copy];
  }
  return self;
}

- (void)dealloc {
  unlink([_temporaryPath fileSystemRepresentation]);
}

- (NSString*)description {
  return [NSString stringWithFormat:@"<%@ | '%@' | '%@>'", [self class], self.mimeType, _fileName];
}

@end

@interface GCDWebServerMIMEStreamParser () {
@private
  NSData* _boundary;
  NSString* _defaultcontrolName;
  ParserState _state;
  NSMutableData* _data;
  NSMutableArray* _arguments;
  NSMutableArray* _files;
  
  NSString* _controlName;
  NSString* _fileName;
  NSString* _contentType;
  NSString* _tmpPath;
  int _tmpFile;
  GCDWebServerMIMEStreamParser* _subParser;
}
@end

@implementation GCDWebServerMIMEStreamParser

+ (void)initialize {
  if (_newlineData == nil) {
    _newlineData = [[NSData alloc] initWithBytes:"\r\n" length:2];
    GWS_DCHECK(_newlineData);
  }
  if (_newlinesData == nil) {
    _newlinesData = [[NSData alloc] initWithBytes:"\r\n\r\n" length:4];
    GWS_DCHECK(_newlinesData);
  }
  if (_dashNewlineData == nil) {
    _dashNewlineData = [[NSData alloc] initWithBytes:"--\r\n" length:4];
    GWS_DCHECK(_dashNewlineData);
  }
}

- (id)initWithBoundary:(NSString*)boundary defaultControlName:(NSString*)name arguments:(NSMutableArray*)arguments files:(NSMutableArray*)files {
  NSData* data = boundary.length ? [[NSString stringWithFormat:@"--%@", boundary] dataUsingEncoding:NSASCIIStringEncoding] : nil;
  if (data == nil) {
    GWS_DNOT_REACHED();
    return nil;
  }
  if ((self = [super init])) {
    _boundary = data;
    _defaultcontrolName = name;
    _arguments = arguments;
    _files = files;
    _data = [[NSMutableData alloc] initWithCapacity:kMultiPartBufferSize];
    _state = kParserState_Start;
  }
  return self;
}

- (void)dealloc {
  if (_tmpFile > 0) {
    close(_tmpFile);
    unlink([_tmpPath fileSystemRepresentation]);
  }
}

// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2
- (BOOL)_parseData {
  BOOL success = YES;
  
  if (_state == kParserState_Headers) {
    NSRange range = [_data rangeOfData:_newlinesData options:0 range:NSMakeRange(0, _data.length)];
    if (range.location != NSNotFound) {
      
      _controlName = nil;
      _fileName = nil;
      _contentType = nil;
      _tmpPath = nil;
      _subParser = nil;
      NSString* headers = [[NSString alloc] initWithData:[_data subdataWithRange:NSMakeRange(0, range.location)] encoding:NSUTF8StringEncoding];
      if (headers) {
        for (NSString* header in [headers componentsSeparatedByString:@"\r\n"]) {
          NSRange subRange = [header rangeOfString:@":"];
          if (subRange.location != NSNotFound) {
            NSString* name = [header substringToIndex:subRange.location];
            NSString* value = [[header substringFromIndex:(subRange.location + subRange.length)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
            if ([name caseInsensitiveCompare:@"Content-Type"] == NSOrderedSame) {
              _contentType = GCDWebServerNormalizeHeaderValue(value);
            } else if ([name caseInsensitiveCompare:@"Content-Disposition"] == NSOrderedSame) {
              NSString* contentDisposition = GCDWebServerNormalizeHeaderValue(value);
              if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"form-data"]) {
                _controlName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"name");
                _fileName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename");
              } else if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"file"]) {
                _controlName = _defaultcontrolName;
                _fileName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename");
              }
            }
          } else {
            GWS_DNOT_REACHED();
          }
        }
        if (_contentType == nil) {
          _contentType = @"text/plain";
        }
      } else {
        GWS_LOG_ERROR(@"Failed decoding headers in part of 'multipart/form-data'");
        GWS_DNOT_REACHED();
      }
      if (_controlName) {
        if ([GCDWebServerTruncateHeaderValue(_contentType) isEqualToString:@"multipart/mixed"]) {
          NSString* boundary = GCDWebServerExtractHeaderValueParameter(_contentType, @"boundary");
          _subParser = [[GCDWebServerMIMEStreamParser alloc] initWithBoundary:boundary defaultControlName:_controlName arguments:_arguments files:_files];
          if (_subParser == nil) {
            GWS_DNOT_REACHED();
            success = NO;
          }
        } else if (_fileName) {
          NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
          _tmpFile = open([path fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
          if (_tmpFile > 0) {
            _tmpPath = [path copy];
          } else {
            GWS_DNOT_REACHED();
            success = NO;
          }
        }
      } else {
        GWS_DNOT_REACHED();
        success = NO;
      }
      
      [_data replaceBytesInRange:NSMakeRange(0, range.location + range.length) withBytes:NULL length:0];
      _state = kParserState_Content;
    }
  }
  
  if ((_state == kParserState_Start) || (_state == kParserState_Content)) {
    NSRange range = [_data rangeOfData:_boundary options:0 range:NSMakeRange(0, _data.length)];
    if (range.location != NSNotFound) {
      NSRange subRange = NSMakeRange(range.location + range.length, _data.length - range.location - range.length);
      NSRange subRange1 = [_data rangeOfData:_newlineData options:NSDataSearchAnchored range:subRange];
      NSRange subRange2 = [_data rangeOfData:_dashNewlineData options:NSDataSearchAnchored range:subRange];
      if ((subRange1.location != NSNotFound) || (subRange2.location != NSNotFound)) {
        
        if (_state == kParserState_Content) {
          const void* dataBytes = _data.bytes;
          NSUInteger dataLength = range.location - 2;
          if (_subParser) {
            if (![_subParser appendBytes:dataBytes length:(dataLength + 2)] || ![_subParser isAtEnd]) {
              GWS_DNOT_REACHED();
              success = NO;
            }
            _subParser = nil;
          } else if (_tmpPath) {
            ssize_t result = write(_tmpFile, dataBytes, dataLength);
            if (result == (ssize_t)dataLength) {
              if (close(_tmpFile) == 0) {
                _tmpFile = 0;
                GCDWebServerMultiPartFile* file = [[GCDWebServerMultiPartFile alloc] initWithControlName:_controlName contentType:_contentType fileName:_fileName temporaryPath:_tmpPath];
                [_files addObject:file];
              } else {
                GWS_DNOT_REACHED();
                success = NO;
              }
            } else {
              GWS_DNOT_REACHED();
              success = NO;
            }
            _tmpPath = nil;
          } else {
            NSData* data = [[NSData alloc] initWithBytes:(void*)dataBytes length:dataLength];
            GCDWebServerMultiPartArgument* argument = [[GCDWebServerMultiPartArgument alloc] initWithControlName:_controlName contentType:_contentType data:data];
            [_arguments addObject:argument];
          }
        }
        
        if (subRange1.location != NSNotFound) {
          [_data replaceBytesInRange:NSMakeRange(0, subRange1.location + subRange1.length) withBytes:NULL length:0];
          _state = kParserState_Headers;
          success = [self _parseData];
        } else {
          _state = kParserState_End;
        }
      }
    } else {
      NSUInteger margin = 2 * _boundary.length;
      if (_data.length > margin) {
        NSUInteger length = _data.length - margin;
        if (_subParser) {
          if ([_subParser appendBytes:_data.bytes length:length]) {
            [_data replaceBytesInRange:NSMakeRange(0, length) withBytes:NULL length:0];
          } else {
            GWS_DNOT_REACHED();
            success = NO;
          }
        } else if (_tmpPath) {
          ssize_t result = write(_tmpFile, _data.bytes, length);
          if (result == (ssize_t)length) {
            [_data replaceBytesInRange:NSMakeRange(0, length) withBytes:NULL length:0];
          } else {
            GWS_DNOT_REACHED();
            success = NO;
          }
        }
      }
    }
  }
  
  return success;
}

- (BOOL)appendBytes:(const void*)bytes length:(NSUInteger)length {
  [_data appendBytes:bytes length:length];
  return [self _parseData];
}

- (BOOL)isAtEnd {
  return (_state == kParserState_End);
}

@end

@interface GCDWebServerMultiPartFormRequest () {
@private
  GCDWebServerMIMEStreamParser* _parser;
  NSMutableArray* _arguments;
  NSMutableArray* _files;
}
@end

@implementation GCDWebServerMultiPartFormRequest

@synthesize arguments=_arguments, files=_files;

+ (NSString*)mimeType {
  return @"multipart/form-data";
}

- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
  if ((self = [super initWithMethod:method url:url headers:headers path:path query:query])) {
    _arguments = [[NSMutableArray alloc] init];
    _files = [[NSMutableArray alloc] init];
  }
  return self;
}

- (BOOL)open:(NSError**)error {
  NSString* boundary = GCDWebServerExtractHeaderValueParameter(self.contentType, @"boundary");
  _parser = [[GCDWebServerMIMEStreamParser alloc] initWithBoundary:boundary defaultControlName:nil arguments:_arguments files:_files];
  if (_parser == nil) {
    if (error) {
      *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed starting to parse multipart form data"}];
    }
    return NO;
  }
  return YES;
}

- (BOOL)writeData:(NSData*)data error:(NSError**)error {
  if (![_parser appendBytes:data.bytes length:data.length]) {
    if (error) {
      *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed continuing to parse multipart form data"}];
    }
    return NO;
  }
  return YES;
}

- (BOOL)close:(NSError**)error {
  BOOL atEnd = [_parser isAtEnd];
  _parser = nil;
  if (!atEnd) {
    if (error) {
      *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed finishing to parse multipart form data"}];
    }
    return NO;
  }
  return YES;
}

- (GCDWebServerMultiPartArgument*)firstArgumentForControlName:(NSString*)name {
  for (GCDWebServerMultiPartArgument* argument in _arguments) {
    if ([argument.controlName isEqualToString:name]) {
      return argument;
    }
  }
  return nil;
}

- (GCDWebServerMultiPartFile*)firstFileForControlName:(NSString*)name {
  for (GCDWebServerMultiPartFile* file in _files) {
    if ([file.controlName isEqualToString:name]) {
      return file;
    }
  }
  return nil;
}

- (NSString*)description {
  NSMutableString* description = [NSMutableString stringWithString:[super description]];
  if (_arguments.count) {
    [description appendString:@"\n"];
    for (GCDWebServerMultiPartArgument* argument in _arguments) {
      [description appendFormat:@"\n%@ (%@)\n", argument.controlName, argument.contentType];
      [description appendString:GCDWebServerDescribeData(argument.data, argument.contentType)];
    }
  }
  if (_files.count) {
    [description appendString:@"\n"];
    for (GCDWebServerMultiPartFile* file in _files) {
      [description appendFormat:@"\n%@ (%@): %@\n{%@}", file.controlName, file.contentType, file.fileName, file.temporaryPath];
    }
  }
  return description;
}

@end
