// Copyright 2010, 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 "breakpad_googletest_includes.h"
#include "client/windows/crash_generation/crash_generation_server.h"
#include "client/windows/common/ipc_protocol.h"

using testing::_;

namespace {

const wchar_t kPipeName[] =
  L"\\\\.\\pipe\\CrashGenerationServerTest\\TestCaseServer";

const DWORD kPipeDesiredAccess = FILE_READ_DATA |
                                 FILE_WRITE_DATA |
                                 FILE_WRITE_ATTRIBUTES;

const DWORD kPipeFlagsAndAttributes = SECURITY_IDENTIFICATION |
                                      SECURITY_SQOS_PRESENT;

const DWORD kPipeMode = PIPE_READMODE_MESSAGE;

#define arraysize(f) (sizeof(f) / sizeof(*f))
const google_breakpad::CustomInfoEntry kCustomInfoEntries[] = {
    google_breakpad::CustomInfoEntry(L"prod", L"CrashGenerationServerTest"),
    google_breakpad::CustomInfoEntry(L"ver", L"1.0"),
};

class CrashGenerationServerTest : public ::testing::Test {
 public:
  CrashGenerationServerTest()
      : crash_generation_server_(kPipeName,
                                 NULL,
                                 CallOnClientConnected, &mock_callbacks_,
                                 CallOnClientDumpRequested, &mock_callbacks_,
                                 CallOnClientExited, &mock_callbacks_,
                                 CallOnClientUploadRequested, &mock_callbacks_,
                                 false,
                                 NULL),
        thread_id_(0),
        exception_pointers_(NULL) {
    memset(&assert_info_, 0, sizeof(assert_info_));
  }

 protected:
  class MockCrashGenerationServerCallbacks {
   public:
    MOCK_METHOD1(OnClientConnected,
                 void(const google_breakpad::ClientInfo* client_info));
    MOCK_METHOD2(OnClientDumpRequested,
                 void(const google_breakpad::ClientInfo* client_info,
                      const std::wstring* file_path));
    MOCK_METHOD1(OnClientExited,
                 void(const google_breakpad::ClientInfo* client_info));
    MOCK_METHOD1(OnClientUploadRequested,
                 void(const DWORD crash_id));
  };

  enum ClientFault {
    NO_FAULT,
    CLOSE_AFTER_CONNECT,
    SEND_INVALID_REGISTRATION,
    TRUNCATE_REGISTRATION,
    CLOSE_AFTER_REGISTRATION,
    RESPONSE_BUFFER_TOO_SMALL,
    CLOSE_AFTER_RESPONSE,
    SEND_INVALID_ACK
  };

  void SetUp() {
    ASSERT_TRUE(crash_generation_server_.Start());
  }

  void FaultyClient(ClientFault fault_type) {
    HANDLE pipe = CreateFile(kPipeName,
                             kPipeDesiredAccess,
                             0,
                             NULL,
                             OPEN_EXISTING,
                             kPipeFlagsAndAttributes,
                             NULL);

    if (pipe == INVALID_HANDLE_VALUE) {
      ASSERT_EQ(ERROR_PIPE_BUSY, GetLastError());

      // Cannot continue retrying if wait on pipe fails.
      ASSERT_TRUE(WaitNamedPipe(kPipeName, 500));

      pipe = CreateFile(kPipeName,
                        kPipeDesiredAccess,
                        0,
                        NULL,
                        OPEN_EXISTING,
                        kPipeFlagsAndAttributes,
                        NULL);
    }

    ASSERT_NE(pipe, INVALID_HANDLE_VALUE);

    DWORD mode = kPipeMode;
    ASSERT_TRUE(SetNamedPipeHandleState(pipe, &mode, NULL, NULL));

    DoFaultyClient(fault_type, pipe);

    CloseHandle(pipe);
  }

  void DoTestFault(ClientFault fault) {
    EXPECT_CALL(mock_callbacks_, OnClientConnected(_)).Times(0);
    ASSERT_NO_FATAL_FAILURE(FaultyClient(fault));
    ASSERT_NO_FATAL_FAILURE(FaultyClient(fault));
    ASSERT_NO_FATAL_FAILURE(FaultyClient(fault));

    EXPECT_CALL(mock_callbacks_, OnClientConnected(_));

    ASSERT_NO_FATAL_FAILURE(FaultyClient(NO_FAULT));

    // Slight hack. The OnClientConnected is only invoked after the ack is
    // received by the server. At that point, the FaultyClient call has already
    // returned. The best way to wait until the server is done handling that is
    // to send one more ping, whose processing will be blocked by delivery of
    // the OnClientConnected message.
    ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT));
  }

  MockCrashGenerationServerCallbacks mock_callbacks_;

 private:
  // Depends on the caller to successfully open the pipe before invocation and
  // to close it immediately afterwards.
  void DoFaultyClient(ClientFault fault_type, HANDLE pipe) {
    if (fault_type == CLOSE_AFTER_CONNECT) {
      return;
    }

    google_breakpad::CustomClientInfo custom_info = {kCustomInfoEntries,
                                                     arraysize(kCustomInfoEntries)};

    google_breakpad::ProtocolMessage msg(
      fault_type == SEND_INVALID_REGISTRATION ?
        google_breakpad::MESSAGE_TAG_NONE :
        google_breakpad::MESSAGE_TAG_REGISTRATION_REQUEST,
      GetCurrentProcessId(),
      MiniDumpNormal,
      &thread_id_,
      &exception_pointers_,
      &assert_info_,
      custom_info,
      NULL,
      NULL,
      NULL);

    DWORD bytes_count = 0;

    ASSERT_TRUE(WriteFile(pipe,
                          &msg,
                          fault_type == TRUNCATE_REGISTRATION ?
                            sizeof(msg) / 2 : sizeof(msg),
                          &bytes_count,
                          NULL));

    if (fault_type == CLOSE_AFTER_REGISTRATION) {
      return;
    }

    google_breakpad::ProtocolMessage reply;

    if (!ReadFile(pipe,
                  &reply,
                  fault_type == RESPONSE_BUFFER_TOO_SMALL ?
                    sizeof(google_breakpad::ProtocolMessage) / 2 :
                    sizeof(google_breakpad::ProtocolMessage),
                  &bytes_count,
                  NULL)) {
      switch (fault_type) {
        case TRUNCATE_REGISTRATION:
        case RESPONSE_BUFFER_TOO_SMALL:
        case SEND_INVALID_REGISTRATION:
          return;

        default:
          FAIL() << "Unexpectedly failed to register.";
      }
    }

    if (fault_type == CLOSE_AFTER_RESPONSE) {
      return;
    }

    google_breakpad::ProtocolMessage ack_msg;
    ack_msg.tag = google_breakpad::MESSAGE_TAG_REGISTRATION_ACK;

    ASSERT_TRUE(WriteFile(pipe,
                          &ack_msg,
                          SEND_INVALID_ACK ?
                            sizeof(ack_msg) : sizeof(ack_msg) / 2,
                          &bytes_count,
                          NULL));

    return;
  }

  static void CallOnClientConnected(
    void* context, const google_breakpad::ClientInfo* client_info) {
    static_cast<MockCrashGenerationServerCallbacks*>(context)->
      OnClientConnected(client_info);
  }

  static void CallOnClientDumpRequested(
    void* context,
    const google_breakpad::ClientInfo* client_info,
    const std::wstring* file_path) {
    static_cast<MockCrashGenerationServerCallbacks*>(context)->
      OnClientDumpRequested(client_info, file_path);
  }

  static void CallOnClientExited(
    void* context, const google_breakpad::ClientInfo* client_info) {
    static_cast<MockCrashGenerationServerCallbacks*>(context)->
      OnClientExited(client_info);
  }

  static void CallOnClientUploadRequested(void* context, const DWORD crash_id) {
    static_cast<MockCrashGenerationServerCallbacks*>(context)->
      OnClientUploadRequested(crash_id);
  }

  DWORD thread_id_;
  EXCEPTION_POINTERS* exception_pointers_;
  MDRawAssertionInfo assert_info_;

  google_breakpad::CrashGenerationServer crash_generation_server_;
};

TEST_F(CrashGenerationServerTest, PingServerTest) {
  DoTestFault(CLOSE_AFTER_CONNECT);
}

TEST_F(CrashGenerationServerTest, InvalidRegistration) {
  DoTestFault(SEND_INVALID_REGISTRATION);
}

TEST_F(CrashGenerationServerTest, TruncateRegistration) {
  DoTestFault(TRUNCATE_REGISTRATION);
}

TEST_F(CrashGenerationServerTest, CloseAfterRegistration) {
  DoTestFault(CLOSE_AFTER_REGISTRATION);
}

TEST_F(CrashGenerationServerTest, ResponseBufferTooSmall) {
  DoTestFault(RESPONSE_BUFFER_TOO_SMALL);
}

TEST_F(CrashGenerationServerTest, CloseAfterResponse) {
  DoTestFault(CLOSE_AFTER_RESPONSE);
}

// It turns out that, as long as you send one byte, the ACK is accepted and
// registration succeeds.
TEST_F(CrashGenerationServerTest, SendInvalidAck) {
  EXPECT_CALL(mock_callbacks_, OnClientConnected(_));
  ASSERT_NO_FATAL_FAILURE(FaultyClient(SEND_INVALID_ACK));

  // See DoTestFault for an explanation of this line
  ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT));

  EXPECT_CALL(mock_callbacks_, OnClientConnected(_));
  ASSERT_NO_FATAL_FAILURE(FaultyClient(NO_FAULT));

  // See DoTestFault for an explanation of this line
  ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT));
}

}  // anonymous namespace
