// Copyright (c) 2019, 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 "HTTPRequest.h"

#import "util.h"

// As -[NSURLConnection sendSynchronousRequest:returningResponse:error:] has
// been deprecated with iOS 9.0 / OS X 10.11 SDKs, this function re-implements
// it using -[NSURLSession dataTaskWithRequest:completionHandler:] which is
// available on iOS 7+.
static NSData *SendSynchronousNSURLRequest(NSURLRequest *req,
                                           NSURLResponse **outResponse,
                                           NSError **outError) {
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_7_0) &&     \
__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0) ||                      \
(defined(MAC_OS_X_VERSION_MIN_REQUIRED) &&                                 \
defined(MAC_OS_X_VERSION_10_11) &&                                        \
MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11)
  __block NSData* result = nil;
  __block NSError* error = nil;
  __block NSURLResponse* response = nil;
  dispatch_semaphore_t waitSemaphone = dispatch_semaphore_create(0);
  NSURLSessionConfiguration* config = [NSURLSessionConfiguration
                                       defaultSessionConfiguration];
  [config setTimeoutIntervalForRequest:240.0];
  NSURLSession* session = [NSURLSession sessionWithConfiguration:config];
  [[session
    dataTaskWithRequest:req
    completionHandler:^(NSData *data,
                        NSURLResponse *resp,
                        NSError *err) {
      if (outError)
        error = [err retain];
      if (outResponse)
        response = [resp retain];
      if (err == nil)
        result = [data retain];
      dispatch_semaphore_signal(waitSemaphone);
    }] resume];
  dispatch_semaphore_wait(waitSemaphone, DISPATCH_TIME_FOREVER);
  dispatch_release(waitSemaphone);
  if (outError)
    *outError = [error autorelease];
  if (outResponse)
    *outResponse = [response autorelease];
  return [result autorelease];
#else
  return [NSURLConnection sendSynchronousRequest:req
                               returningResponse:outResponse
                                           error:outError];
#endif
}

@implementation HTTPRequest

//=============================================================================
- (id)initWithURL:(NSURL *)URL {
    if ((self = [super init])) {
        URL_ = [URL copy];
    }
    
    return self;
}

//=============================================================================
- (void)dealloc {
    [URL_ release];
    [response_ release];
    
    [super dealloc];
}

//=============================================================================
- (NSURL *)URL {
    return URL_;
}

//=============================================================================
- (NSHTTPURLResponse *)response {
    return response_;
}

//=============================================================================
- (NSString*)HTTPMethod {
    @throw [NSException exceptionWithName:NSInternalInconsistencyException
                                   reason:[NSString stringWithFormat:@"You must"
                                           "override %@ in a subclass",
                                           NSStringFromSelector(_cmd)]
                                 userInfo:nil];
}

//=============================================================================
- (NSString*)contentType {
    return nil;
}

//=============================================================================
- (NSData*)bodyData {
  return nil;
}

//=============================================================================
- (NSData *)send:(NSError **)withError {
  NSMutableURLRequest *req =
  [[NSMutableURLRequest alloc]
   initWithURL:URL_
   cachePolicy:NSURLRequestUseProtocolCachePolicy
   timeoutInterval:60.0];
  
  NSString* contentType = [self contentType];
  if ([contentType length] > 0) {
    [req setValue:contentType forHTTPHeaderField:@"Content-type"];
  }
  
  NSData* bodyData = [self bodyData];
  if ([bodyData length] > 0) {
    [req setHTTPBody:bodyData];
  }
  
  [req setHTTPMethod:[self HTTPMethod]];
  
  [response_ release];
  response_ = nil;
  
  NSData *data = nil;
  if ([[req URL] isFileURL]) {
    [[req HTTPBody] writeToURL:[req URL] options:0 error:withError];
  } else {
    NSURLResponse *response = nil;
    data = SendSynchronousNSURLRequest(req, &response, withError);
    response_ = (NSHTTPURLResponse *)[response retain];
  }
  [req release];
  
  return data;
}

//=============================================================================
+ (NSData *)formDataForFileContents:(NSData *)contents
                           withName:(NSString *)name {
  NSMutableData *data = [NSMutableData data];
  NSString *escaped = PercentEncodeNSString(name);
  NSString *fmt = @"Content-Disposition: form-data; name=\"%@\"; "
    "filename=\"minidump.dmp\"\r\nContent-Type: "
    "application/octet-stream\r\n\r\n";
  NSString *pre = [NSString stringWithFormat:fmt, escaped];
  
  [data appendData:[pre dataUsingEncoding:NSUTF8StringEncoding]];
  [data appendData:contents];
  
  return data;
}

//=============================================================================
+ (NSData *)formDataForFile:(NSString *)file withName:(NSString *)name {
  NSData *contents = [NSData dataWithContentsOfFile:file];
  
  return [HTTPRequest formDataForFileContents:contents withName:name];
}

//=============================================================================
+ (NSData *)formDataForKey:(NSString *)key value:(NSString *)value {
  NSString *escaped = PercentEncodeNSString(key);
  NSString *fmt =
    @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n";
  NSString *form = [NSString stringWithFormat:fmt, escaped, value];
  
  return [form dataUsingEncoding:NSUTF8StringEncoding];
}

//=============================================================================
+ (void)appendFileToBodyData:(NSMutableData *)data
                    withName:(NSString*)name
              withFileOrData:(id)fileOrData {
  NSData *fileData;
  
  // The object can be either the path to a file (NSString) or the contents
  // of the file (NSData).
  if ([fileOrData isKindOfClass:[NSData class]])
    fileData = [self formDataForFileContents:fileOrData withName:name];
  else
    fileData = [HTTPRequest formDataForFile:fileOrData withName:name];
  
  [data appendData:fileData];
}

@end
