// Copyright 2010-2015, 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 <Imagehlp.h>
#include <SoftPub.h>
#include <Wintrust.h>

#include <memory>
#include <sstream>
#include <string>

#include "base/const.h"
#include "base/logging.h"
#include "base/run_level.h"
#include "base/util.h"
#include "base/win_util.h"
#include "client/client_interface.h"
#include "renderer/renderer_client.h"
#include "win32/base/file_verifier.h"
#include "win32/base/imm_util.h"
#include "win32/broker/mozc_broker_resource.h"

namespace mozc {
namespace win32 {
namespace {

using std::unique_ptr;

const int kErrorLevelSuccess = 0;
const int kErrorLevelGeneralError = 1;
const int kErrorLevelCorruptedFileDetected = 2;

wstring LoadStringResource(int resource_id) {
  wchar_t buffer[4096] = {};
  const int copied_chars_without_null =
      ::LoadString(::GetModuleHandleW(nullptr), resource_id,
      buffer, arraysize(buffer));

  if (copied_chars_without_null == arraysize(buffer)) {
    DLOG(ERROR) << "Message is truncated.";
    return L"";
  }

  return wstring(buffer, copied_chars_without_null);
}

void EnterBackgroundThreadMode() {
  // GetCurrentThread returns pseudo handle, which you need not
  // to pass CloseHandle.
  const HANDLE thread_handle = ::GetCurrentThread();

  // Enter low priority mode.
  ::SetThreadPriority(thread_handle, THREAD_MODE_BACKGROUND_BEGIN);
}

}  // namespace

int RunPrelaunchProcesses(int argc, char *argv[]) {
  if (RunLevel::IsProcessInJob()) {
    return kErrorLevelGeneralError;
  }

  bool is_service_process = false;
  if (!WinUtil::IsServiceProcess(&is_service_process)) {
    // Returns DENY conservatively.
    return kErrorLevelGeneralError;
  }
  if (is_service_process) {
    return kErrorLevelGeneralError;
  }

  if (!ImeUtil::IsDefault()) {
    // If Mozc is not default, do nothing.
    return kErrorLevelSuccess;
  }

  // To keep performance impact minimum, set current thread as background.
  // On Vista and later, all the I/O including page faults well be handled
  // in low priority if the thread is marked as background.
  EnterBackgroundThreadMode();

  const FileVerifier::MozcSystemFile kSourceFiles[] = {
    FileVerifier::kMozcServerFile,
    FileVerifier::kMozcRendererFile,
    FileVerifier::kMozcToolFile,
  };

  wstringstream missing_files;
  wstringstream corrupted_files;
  for (size_t i = 0; i < arraysize(kSourceFiles); ++i) {
    string fileinfo;
    const FileVerifier::IntegrityType integrity_type =
        FileVerifier::VerifyIntegrity(kSourceFiles[i], &fileinfo);
    switch (integrity_type) {
      case FileVerifier::kIntegrityCorrupted: {
        wstring wfileinfo;
        Util::UTF8ToWide(fileinfo, &wfileinfo);
        corrupted_files << L"\r\n  " << wfileinfo;
        break;
      }
      case FileVerifier::kIntegrityFileNotFound: {
        wstring wfileinfo;
        Util::UTF8ToWide(fileinfo, &wfileinfo);
        missing_files << L"\r\n  " << wfileinfo;
        break;
      }
    }
  }

  const wstring &corrupted_files_str = corrupted_files.str();
  const wstring &missing_files_str = missing_files.str();
  if (!corrupted_files_str.empty() || !missing_files_str.empty()) {
    wstringstream message;
    message << LoadStringResource(IDS_DIALOG_MESSAGE);
    if (!corrupted_files_str.empty()) {
      message << L"\r\n" << LoadStringResource(IDS_DIALOG_FILE_CORRUPTED)
              << L":" << corrupted_files_str;
    }
    if (!missing_files_str.empty()) {
      message << L"\r\n" << LoadStringResource(IDS_DIALOG_FILE_NOT_FOUND)
              << L":" << missing_files_str;
    }
    ::MessageBoxW(nullptr, message.str().c_str(),
                  LoadStringResource(IDS_DIALOG_TITLE).c_str(),
                  MB_OK | MB_ICONERROR | MB_DEFAULT_DESKTOP_ONLY);
    return kErrorLevelCorruptedFileDetected;
  }

  {
    unique_ptr<client::ClientInterface> converter_client(
        client::ClientFactory::NewClient());
    converter_client->set_suppress_error_dialog(true);
    converter_client->EnsureConnection();
  }

  {
    unique_ptr<renderer::RendererClient> renderer_client(
        new mozc::renderer::RendererClient);
    renderer_client->set_suppress_error_dialog(true);
    renderer_client->Activate();
  }

  return kErrorLevelSuccess;
}

}  // namespace win32
}  // namespace mozc
