// Copyright (c) 2006, Google Inc.
// 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.
//     * Neither the name of Google Inc. nor the names of its
// contributors may 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 THE COPYRIGHT
// OWNER 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.

#import "HTTPMultipartUpload.h"

#import "GTMDefines.h"
#import "encoding_util.h"

@interface HTTPMultipartUpload (PrivateMethods)
- (NSString*)multipartBoundary;
// Each of the following methods will append the starting multipart boundary,
// but not the ending one.
- (NSData*)formDataForKey:(NSString*)key value:(NSString*)value;
- (NSData*)formDataForFileContents:(NSData*)contents name:(NSString*)name;
- (NSData*)formDataForFile:(NSString*)file name:(NSString*)name;
@end

@implementation HTTPMultipartUpload
//=============================================================================
#pragma mark -
#pragma mark || Private ||
//=============================================================================
- (NSString*)multipartBoundary {
  // The boundary has 27 '-' characters followed by 16 hex digits
  return [NSString
      stringWithFormat:@"---------------------------%08X%08X", rand(), rand()];
}

//=============================================================================
- (NSData*)formDataForKey:(NSString*)key value:(NSString*)value {
  NSMutableData* data = [NSMutableData data];
  [self appendBoundaryData:data];

  NSString* escaped = PercentEncodeNSString(key);
  NSString* fmt = @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n";
  NSString* form = [NSString stringWithFormat:fmt, boundary_, escaped, value];

  [data appendData:[form dataUsingEncoding:NSUTF8StringEncoding]];
  return data;
}

//=============================================================================
- (void)appendBoundaryData:(NSMutableData*)data {
  NSString* fmt = @"--%@\r\n";
  NSString* pre = [NSString stringWithFormat:fmt, boundary_];

  [data appendData:[pre dataUsingEncoding:NSUTF8StringEncoding]];
}

//=============================================================================
#pragma mark -
#pragma mark || Public ||
//=============================================================================
- (id)initWithURL:(NSURL*)url {
  if ((self = [super initWithURL:url])) {
    boundary_ = [[self multipartBoundary] retain];
    files_ = [[NSMutableDictionary alloc] init];
  }

  return self;
}

//=============================================================================
- (void)dealloc {
  [parameters_ release];
  [files_ release];
  [boundary_ release];

  [super dealloc];
}

//=============================================================================
- (void)setParameters:(NSDictionary*)parameters {
  if (parameters != parameters_) {
    [parameters_ release];
    parameters_ = [parameters copy];
  }
}

//=============================================================================
- (NSDictionary*)parameters {
  return parameters_;
}

//=============================================================================
- (void)addFileAtPath:(NSString*)path name:(NSString*)name {
  [files_ setObject:path forKey:name];
}

//=============================================================================
- (void)addFileContents:(NSData*)data name:(NSString*)name {
  [files_ setObject:data forKey:name];
}

//=============================================================================
- (NSDictionary*)files {
  return files_;
}

//=============================================================================
- (NSString*)HTTPMethod {
  return @"POST";
}

//=============================================================================
- (NSString*)contentType {
  return [NSString
      stringWithFormat:@"multipart/form-data; boundary=%@", boundary_];
}

//=============================================================================
- (NSData*)bodyData {
  NSMutableData* postBody = [NSMutableData data];

  // Add any parameters to the message
  NSArray* parameterKeys = [parameters_ allKeys];
  NSString* key;

  NSInteger count = [parameterKeys count];
  for (NSInteger i = 0; i < count; ++i) {
    key = [parameterKeys objectAtIndex:i];
    [postBody appendData:[self formDataForKey:key
                                        value:[parameters_ objectForKey:key]]];
  }

  // Add any files to the message
  NSArray* fileNames = [files_ allKeys];
  for (NSString* name in fileNames) {
    // First append boundary
    [self appendBoundaryData:postBody];
    // Then the formdata
    id fileOrData = [files_ objectForKey:name];
    [HTTPRequest appendFileToBodyData:postBody
                             withName:name
                       withFileOrData:fileOrData];
  }

  NSString* epilogue = [NSString stringWithFormat:@"\r\n--%@--\r\n", boundary_];
  [postBody appendData:[epilogue dataUsingEncoding:NSUTF8StringEncoding]];

  return postBody;
}

@end
