// Copyright 2006 Google LLC
//
// 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 LLC 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.

// minidump_upload.m: Upload a minidump to a HTTP server.  The upload is sent as
// a multipart/form-data POST request with the following parameters:
//  prod: the product name
//  ver: the product version
//  symbol_file: the breakpad format symbol file

#import <unistd.h>

#import <Foundation/Foundation.h>

#import "common/mac/HTTPMultipartUpload.h"

typedef struct {
  NSString* minidumpPath;
  NSString* uploadURLStr;
  NSString* product;
  NSString* version;
  BOOL success;
} Options;

//=============================================================================
static void Start(Options* options) {
  NSURL* url = [NSURL URLWithString:options->uploadURLStr];
  HTTPMultipartUpload* ul = [[HTTPMultipartUpload alloc] initWithURL:url];
  NSMutableDictionary* parameters = [NSMutableDictionary dictionary];

  // Add parameters
  [parameters setObject:options->product forKey:@"prod"];
  [parameters setObject:options->version forKey:@"ver"];
  [ul setParameters:parameters];

  // Add file
  [ul addFileAtPath:options->minidumpPath name:@"upload_file_minidump"];

  // Send it
  NSError* error = nil;
  NSData* data = [ul send:&error];
  NSString* result = [[NSString alloc] initWithData:data
                                           encoding:NSUTF8StringEncoding];

  NSLog(@"Send: %@", error ? [error description] : @"No Error");
  NSLog(@"Response: %ld", (long)[[ul response] statusCode]);
  NSLog(@"Result: %lu bytes\n%@", (unsigned long)[data length], result);

  [result release];
  [ul release];
  options->success = !error;
}

//=============================================================================
static void Usage(int argc, const char* argv[]) {
  fprintf(stderr, "Submit minidump information.\n");
  fprintf(stderr,
          "Usage: %s -p <product> -v <version> <minidump> "
          "<upload-URL>\n",
          argv[0]);
  fprintf(stderr, "<minidump> should be a minidump.\n");
  fprintf(stderr, "<upload-URL> is the destination for the upload\n");

  fprintf(stderr, "\t-h: Usage\n");
  fprintf(stderr, "\t-?: Usage\n");
}

//=============================================================================
static void SetupOptions(int argc, const char* argv[], Options* options) {
  extern int optind;
  char ch;

  while ((ch = getopt(argc, (char* const*)argv, "p:v:h?")) != -1) {
    switch (ch) {
      case 'p':
        options->product = [NSString stringWithUTF8String:optarg];
        break;
      case 'v':
        options->version = [NSString stringWithUTF8String:optarg];
        break;

      default:
        Usage(argc, argv);
        exit(0);
        break;
    }
  }

  if ((argc - optind) != 2) {
    fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]);
    Usage(argc, argv);
    exit(1);
  }

  options->minidumpPath = [NSString stringWithUTF8String:argv[optind]];
  options->uploadURLStr = [NSString stringWithUTF8String:argv[optind + 1]];
}

//=============================================================================
int main(int argc, const char* argv[]) {
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  Options options;

  bzero(&options, sizeof(Options));
  SetupOptions(argc, argv, &options);
  Start(&options);

  [pool release];
  return options.success ? 0 : 1;
}
