// 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.

// Tool to upload an exe/dll and its associated symbols to an HTTP server.
// The PDB file is located automatically, using the path embedded in the
// executable.  The upload is sent as a multipart/form-data POST request,
// with the following parameters:
//  code_file: the basename of the module, e.g. "app.exe"
//  debug_file: the basename of the debugging file, e.g. "app.pdb"
//  debug_identifier: the debug file's identifier, usually consisting of
//                    the guid and age embedded in the pdb, e.g.
//                    "11111111BBBB3333DDDD555555555555F"
//  product: the HTTP-friendly product name, e.g. "MyApp"
//  version: the file version of the module, e.g. "1.2.3.4"
//  os: the operating system that the module was built for, always
//      "windows" in this implementation.
//  cpu: the CPU that the module was built for, typically "x86".
//  symbol_file: the contents of the breakpad-format symbol file

#include <windows.h>
#include <dbghelp.h>
#include <wininet.h>

#include <cstdio>
#include <map>
#include <string>
#include <vector>

#include "common/windows/string_utils-inl.h"

#include "common/windows/http_upload.h"
#include "common/windows/pdb_source_line_writer.h"
#include "common/windows/symbol_collector_client.h"

using std::string;
using std::wstring;
using std::vector;
using std::map;
using google_breakpad::HTTPUpload;
using google_breakpad::SymbolCollectorClient;
using google_breakpad::SymbolStatus;
using google_breakpad::UploadUrlResponse;
using google_breakpad::CompleteUploadResult;
using google_breakpad::PDBModuleInfo;
using google_breakpad::PDBSourceLineWriter;
using google_breakpad::WindowsStringUtils;

// Extracts the file version information for the given filename,
// as a string, for example, "1.2.3.4".  Returns true on success.
static bool GetFileVersionString(const wchar_t *filename, wstring *version) {
  DWORD handle;
  DWORD version_size = GetFileVersionInfoSize(filename, &handle);
  if (version_size < sizeof(VS_FIXEDFILEINFO)) {
    return false;
  }

  vector<char> version_info(version_size);
  if (!GetFileVersionInfo(filename, handle, version_size, &version_info[0])) {
    return false;
  }

  void *file_info_buffer = NULL;
  unsigned int file_info_length;
  if (!VerQueryValue(&version_info[0], L"\\",
                     &file_info_buffer, &file_info_length)) {
    return false;
  }

  // The maximum value of each version component is 65535 (0xffff),
  // so the max length is 24, including the terminating null.
  wchar_t ver_string[24];
  VS_FIXEDFILEINFO *file_info =
    reinterpret_cast<VS_FIXEDFILEINFO*>(file_info_buffer);
  swprintf(ver_string, sizeof(ver_string) / sizeof(ver_string[0]),
           L"%d.%d.%d.%d",
           file_info->dwFileVersionMS >> 16,
           file_info->dwFileVersionMS & 0xffff,
           file_info->dwFileVersionLS >> 16,
           file_info->dwFileVersionLS & 0xffff);

  // remove when VC++7.1 is no longer supported
  ver_string[sizeof(ver_string) / sizeof(ver_string[0]) - 1] = L'\0';

  *version = ver_string;
  return true;
}

// Creates a new temporary file and writes the symbol data from the given
// exe/dll file to it.  Returns the path to the temp file in temp_file_path
// and information about the pdb in pdb_info.
static bool DumpSymbolsToTempFile(const wchar_t *file,
                                  wstring *temp_file_path,
                                  PDBModuleInfo *pdb_info) {
  google_breakpad::PDBSourceLineWriter writer;
  // Use EXE_FILE to get information out of the exe/dll in addition to the
  // pdb.  The name and version number of the exe/dll are of value, and
  // there's no way to locate an exe/dll given a pdb.
  if (!writer.Open(file, PDBSourceLineWriter::EXE_FILE)) {
    return false;
  }

  wchar_t temp_path[_MAX_PATH];
  if (GetTempPath(_MAX_PATH, temp_path) == 0) {
    return false;
  }

  wchar_t temp_filename[_MAX_PATH];
  if (GetTempFileName(temp_path, L"sym", 0, temp_filename) == 0) {
    return false;
  }

  FILE *temp_file = NULL;
#if _MSC_VER >= 1400  // MSVC 2005/8
  if (_wfopen_s(&temp_file, temp_filename, L"w") != 0)
#else  // _MSC_VER >= 1400
  // _wfopen_s was introduced in MSVC8.  Use _wfopen for earlier environments.
  // Don't use it with MSVC8 and later, because it's deprecated.
  if (!(temp_file = _wfopen(temp_filename, L"w")))
#endif  // _MSC_VER >= 1400
  {
    return false;
  }

  bool success = writer.WriteMap(temp_file);
  fclose(temp_file);
  if (!success) {
    _wunlink(temp_filename);
    return false;
  }

  *temp_file_path = temp_filename;

  return writer.GetModuleInfo(pdb_info);
}

static bool DoSymUploadV2(
    const wchar_t* api_url,
    const wchar_t* api_key,
    const wstring& debug_file,
    const wstring& debug_id,
    const wstring& symbol_file,
    bool force) {
  wstring url(api_url);
  wstring key(api_key);

  if (!force) {
    SymbolStatus symbolStatus = SymbolCollectorClient::CheckSymbolStatus(
      url,
      key,
      debug_file,
      debug_id);
    if (symbolStatus == SymbolStatus::Found) {
      wprintf(L"Symbol file already exists, upload aborted."
        L" Use \"-f\" to overwrite.\n");
      return true;
    }
    else if (symbolStatus == SymbolStatus::Unknown) {
      wprintf(L"Failed to get check for existing symbol.\n");
      return false;
    }
  }

  UploadUrlResponse uploadUrlResponse;
  if (!SymbolCollectorClient::CreateUploadUrl(
      url,
      key,
      &uploadUrlResponse)) {
    wprintf(L"Failed to create upload URL.\n");
    return false;
  }

  wstring signed_url = uploadUrlResponse.upload_url;
  wstring upload_key = uploadUrlResponse.upload_key;
  wstring response;
  int response_code;
  bool success = HTTPUpload::SendPutRequest(
    signed_url,
    symbol_file,
    /* timeout = */ NULL,
    &response,
    &response_code);
  if (!success) {
    wprintf(L"Failed to send symbol file.\n");
    wprintf(L"Response code: %ld\n", response_code);
    wprintf(L"Response:\n");
    wprintf(L"%s\n", response.c_str());
    return false;
  }
  else if (response_code == 0) {
    wprintf(L"Failed to send symbol file: No response code\n");
    return false;
  }
  else if (response_code != 200) {
    wprintf(L"Failed to send symbol file: Response code %ld\n", response_code);
    wprintf(L"Response:\n");
    wprintf(L"%s\n", response.c_str());
    return false;
  }

  CompleteUploadResult completeUploadResult =
    SymbolCollectorClient::CompleteUpload(
      url,
      key,
      upload_key,
      debug_file,
      debug_id);
  if (completeUploadResult == CompleteUploadResult::Error) {
    wprintf(L"Failed to complete upload.\n");
    return false;
  }
  else if (completeUploadResult == CompleteUploadResult::DuplicateData) {
    wprintf(L"Uploaded file checksum matched existing file checksum,"
      L" no change necessary.\n");
  }
  else {
    wprintf(L"Successfully sent the symbol file.\n");
  }

  return true;
}

__declspec(noreturn) void printUsageAndExit() {
  wprintf(L"Usage:\n\n"
          L"    symupload [--timeout NN] [--product product_name] ^\n"
          L"              <file.exe|file.dll> <symbol upload URL> ^\n"
          L"              [...<symbol upload URLs>]\n\n");
  wprintf(L"  - Timeout is in milliseconds, or can be 0 to be unlimited.\n");
  wprintf(L"  - product_name is an HTTP-friendly product name. It must only\n"
          L"    contain an ascii subset: alphanumeric and punctuation.\n"
          L"    This string is case-sensitive.\n\n");
  wprintf(L"Example:\n\n"
          L"    symupload.exe --timeout 0 --product Chrome ^\n"
          L"        chrome.dll http://no.free.symbol.server.for.you\n");
  wprintf(L"\n");
  wprintf(L"sym-upload-v2 usage:\n"
          L"    symupload -p [-f] <file.exe|file.dll> <API-URL> <API-key>\n");
  wprintf(L"\n");
  wprintf(L"sym_upload_v2 Options:\n");
  wprintf(L"    <API-URL> is the sym_upload_v2 API URL.\n");
  wprintf(L"    <API-key> is a secret used to authenticate with the API.\n");
  wprintf(L"    -p:\t Use sym_upload_v2 protocol.\n");
  wprintf(L"    -f:\t Force symbol upload if already exists.\n");

  exit(0);
}

int wmain(int argc, wchar_t *argv[]) {
  const wchar_t *module;
  const wchar_t *product = nullptr;
  int timeout = -1;
  int currentarg = 1;
  bool use_sym_upload_v2 = false;
  bool force = false;
  const wchar_t* api_url = nullptr;
  const wchar_t* api_key = nullptr;
  while (argc > currentarg + 1) {
    if (!wcscmp(L"--timeout", argv[currentarg])) {
      timeout = _wtoi(argv[currentarg + 1]);
      currentarg += 2;
      continue;
    }
    if (!wcscmp(L"--product", argv[currentarg])) {
      product = argv[currentarg + 1];
      currentarg += 2;
      continue;
    }
    if (!wcscmp(L"-p", argv[currentarg])) {
      use_sym_upload_v2 = true;
      ++currentarg;
      continue;
    }
    if (!wcscmp(L"-f", argv[currentarg])) {
      force = true;
      ++currentarg;
      continue;
    }
    break;
  }

  if (argc >= currentarg + 2)
    module = argv[currentarg++];
  else
    printUsageAndExit();

  wstring symbol_file;
  PDBModuleInfo pdb_info;
  if (!DumpSymbolsToTempFile(module, &symbol_file, &pdb_info)) {
    fwprintf(stderr, L"Could not get symbol data from %s\n", module);
    return 1;
  }

  wstring code_file = WindowsStringUtils::GetBaseName(wstring(module));
  wstring file_version;
  // Don't make a missing version a hard error.  Issue a warning, and let the
  // server decide whether to reject files without versions.
  if (!GetFileVersionString(module, &file_version)) {
    fwprintf(stderr, L"Warning: Could not get file version for %s\n", module);
  }

  bool success = true;

  if (use_sym_upload_v2) {
    if (argc >= currentarg + 2) {
      api_url = argv[currentarg++];
      api_key = argv[currentarg++];

      success = DoSymUploadV2(
        api_url,
        api_key,
        pdb_info.debug_file,
        pdb_info.debug_identifier,
        symbol_file,
        force);
    } else {
      printUsageAndExit();
    }
  } else {
    map<wstring, wstring> parameters;
    parameters[L"code_file"] = code_file;
    parameters[L"debug_file"] = pdb_info.debug_file;
    parameters[L"debug_identifier"] = pdb_info.debug_identifier;
    parameters[L"os"] = L"windows";  // This version of symupload is Windows-only
    parameters[L"cpu"] = pdb_info.cpu;

    map<wstring, wstring> files;
    files[L"symbol_file"] = symbol_file;

    if (!file_version.empty()) {
      parameters[L"version"] = file_version;
    }

    // Don't make a missing product name a hard error.  Issue a warning and let
    // the server decide whether to reject files without product name.
    if (product) {
      parameters[L"product"] = product;
    }
    else {
      fwprintf(
        stderr,
        L"Warning: No product name (flag --product) was specified for %s\n",
        module);
    }

    while (currentarg < argc) {
      int response_code;
      if (!HTTPUpload::SendMultipartPostRequest(argv[currentarg], parameters, files,
          timeout == -1 ? NULL : &timeout,
          nullptr, &response_code)) {
        success = false;
        fwprintf(stderr,
          L"Symbol file upload to %s failed. Response code = %ld\n",
          argv[currentarg], response_code);
      }
      currentarg++;
    }
  }

  _wunlink(symbol_file.c_str());

  if (success) {
    wprintf(L"Uploaded breakpad symbols for windows-%s/%s/%s (%s %s)\n",
            pdb_info.cpu.c_str(), pdb_info.debug_file.c_str(),
            pdb_info.debug_identifier.c_str(), code_file.c_str(),
            file_version.c_str());
  }

  return success ? 0 : 1;
}
