// Copyright 2003 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.

#include <Windows.h>
#include <shellapi.h>

#include <string>
#include <utility>

#include "breakpad_googletest_includes.h"

namespace tools {
namespace windows {
namespace dump_syms {

namespace {

// Root names of PDB and dumped symbol files to be regression tested. These are
// specified in complexity of the resulting dumped symbol files.
const wchar_t* kRootNames[] = {
  // A PDB file with no OMAP data.
  L"dump_syms_regtest",
  // A PDB file with OMAP data for an image that has been function-level
  // reordered.
  L"omap_reorder_funcs",
  // A PDB file with OMAP data for an image that had new content injected, all
  // of it with source data.
  L"omap_stretched_filled",
  // A PDB file with OMAP data for an image that had new content injected, but
  // without source data.
  L"omap_stretched",
  // A PDB file with OMAP data for an image that has been basic block reordered.
  L"omap_reorder_bbs",  
  // A 64bit PDB file with no OMAP data.
  L"dump_syms_regtest64",
};

void TrimLastComponent(const std::wstring& path,
                       std::wstring* trimmed,
                       std::wstring* component) {
  size_t len = path.size();
  while (len > 0 && path[len - 1] != '\\')
    --len;

  if (component != NULL)
    component->assign(path.c_str() + len, path.c_str() + path.size());

  while (len > 0 && path[len - 1] == '\\')
    --len;

  if (trimmed != NULL)
    trimmed->assign(path.c_str(), len);
}

// Get the directory of the current executable.
bool GetSelfDirectory(std::wstring* self_dir) {
  std::wstring command_line = GetCommandLineW();

  int num_args = 0;
  wchar_t** args = NULL;
  args = ::CommandLineToArgvW(command_line.c_str(), &num_args);
  if (args == NULL)
    return false;

  *self_dir = args[0];
  TrimLastComponent(*self_dir, self_dir, NULL);

  return true;
}

void RunCommand(const std::wstring& command_line,
                std::string* stdout_string) {
  // Create a PIPE for the child process stdout.
  HANDLE child_stdout_read = 0;
  HANDLE child_stdout_write = 0;
  SECURITY_ATTRIBUTES sec_attr_stdout = {};
  sec_attr_stdout.nLength = sizeof(sec_attr_stdout);
  sec_attr_stdout.bInheritHandle = TRUE;
  ASSERT_TRUE(::CreatePipe(&child_stdout_read, &child_stdout_write,
                           &sec_attr_stdout, 0));
  ASSERT_TRUE(::SetHandleInformation(child_stdout_read, HANDLE_FLAG_INHERIT,
                                     0));

  // Create a PIPE for the child process stdin.
  HANDLE child_stdin_read = 0;
  HANDLE child_stdin_write = 0;
  SECURITY_ATTRIBUTES sec_attr_stdin = {};
  sec_attr_stdin.nLength = sizeof(sec_attr_stdin);
  sec_attr_stdin.bInheritHandle = TRUE;
  ASSERT_TRUE(::CreatePipe(&child_stdin_read, &child_stdin_write,
                           &sec_attr_stdin, 0));
  ASSERT_TRUE(::SetHandleInformation(child_stdin_write, HANDLE_FLAG_INHERIT,
                                     0));

  // Startup the child.
  STARTUPINFO startup_info = {};
  PROCESS_INFORMATION process_info = {};
  startup_info.cb = sizeof(STARTUPINFO);
  startup_info.hStdError = NULL;
  startup_info.hStdInput = child_stdin_read;
  startup_info.hStdOutput = child_stdout_write;
  startup_info.dwFlags = STARTF_USESTDHANDLES;
  ASSERT_TRUE(::CreateProcessW(NULL, (LPWSTR)command_line.c_str(), NULL, NULL,
                               TRUE, 0, NULL, NULL,
                               &startup_info, &process_info));

  // Collect the output.
  ASSERT_TRUE(::CloseHandle(child_stdout_write));
  char buffer[4096] = {};
  DWORD bytes_read = 0;
  while (::ReadFile(child_stdout_read, buffer, sizeof(buffer), &bytes_read,
                    NULL) && bytes_read > 0) {
    stdout_string->append(buffer, bytes_read);
  }

  // Wait for the process to finish.
  ::WaitForSingleObject(process_info.hProcess, INFINITE);

  // Shut down all of our handles.
  ASSERT_TRUE(::CloseHandle(process_info.hThread));
  ASSERT_TRUE(::CloseHandle(process_info.hProcess));
  ASSERT_TRUE(::CloseHandle(child_stdin_write));
  ASSERT_TRUE(::CloseHandle(child_stdin_read));
  ASSERT_TRUE(::CloseHandle(child_stdout_read));
}

void GetFileContents(const std::wstring& path, std::string* content) {
  FILE* f = ::_wfopen(path.c_str(), L"rb");
  ASSERT_TRUE(f != NULL);

  char buffer[4096] = {};
  while (true) {
    size_t bytes_read = ::fread(buffer, 1, sizeof(buffer), f);
    if (bytes_read == 0)
      break;
    content->append(buffer, bytes_read);
  }
}

class DumpSymsRegressionTest : public testing::TestWithParam<const wchar_t *> {
 public:
  virtual void SetUp() {
    std::wstring self_dir;
    ASSERT_TRUE(GetSelfDirectory(&self_dir));
    dump_syms_exe = self_dir + L"\\dump_syms.exe";

    TrimLastComponent(self_dir, &testdata_dir, NULL);
    testdata_dir += L"\\testdata";
  }

  std::wstring dump_syms_exe;
  std::wstring testdata_dir;
};

}  //namespace

TEST_P(DumpSymsRegressionTest, EnsureDumpedSymbolsMatch) {
    const wchar_t* root_name = GetParam();
    std::wstring root_path = testdata_dir + L"\\" + root_name;

    std::wstring sym_path = root_path + L".sym";
    std::string expected_symbols;
    ASSERT_NO_FATAL_FAILURE(GetFileContents(sym_path, &expected_symbols));

    std::wstring pdb_path = root_path + L".pdb";
    std::wstring command_line = L"\"" + dump_syms_exe + L"\" \"" +
        pdb_path + L"\"";
    std::string symbols;
    ASSERT_NO_FATAL_FAILURE(RunCommand(command_line, &symbols));

    EXPECT_EQ(expected_symbols, symbols);
}

INSTANTIATE_TEST_CASE_P(DumpSyms, DumpSymsRegressionTest,
                        testing::ValuesIn(kRootNames));


}  // namespace dump_syms
}  // namespace windows
}  // namespace tools
