// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cloud_print/service/win/service_controller.h"

#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/win/scoped_handle.h"
#include "chrome/common/chrome_switches.h"
#include "cloud_print/common/win/cloud_print_utils.h"
#include "cloud_print/service/service_constants.h"
#include "cloud_print/service/service_switches.h"
#include "cloud_print/service/win/chrome_launcher.h"
#include "cloud_print/service/win/local_security_policy.h"
#include "cloud_print/service/win/service_utils.h"

namespace {

const wchar_t kServiceExeName[] = L"cloud_print_service.exe";

// The traits class for Windows Service.
class ServiceHandleTraits {
 public:
  typedef SC_HANDLE Handle;

  // Closes the handle.
  static bool CloseHandle(Handle handle) {
    return ::CloseServiceHandle(handle) != FALSE;
  }

  static bool IsHandleValid(Handle handle) {
    return handle != NULL;
  }

  static Handle NullHandle() {
    return NULL;
  }

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(ServiceHandleTraits);
};

typedef base::win::GenericScopedHandle<
    ServiceHandleTraits, base::win::DummyVerifierTraits> ServiceHandle;

HRESULT OpenServiceManager(ServiceHandle* service_manager) {
  if (!service_manager)
    return E_POINTER;

  service_manager->Set(::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS));
  if (!service_manager->IsValid())
    return cloud_print::GetLastHResult();

  return S_OK;
}

HRESULT OpenService(const base::string16& name, DWORD access,
                    ServiceHandle* service) {
  if (!service)
    return E_POINTER;

  ServiceHandle scm;
  HRESULT hr = OpenServiceManager(&scm);
  if (FAILED(hr))
    return hr;

  service->Set(::OpenService(scm, name.c_str(), access));

  if (!service->IsValid())
    return cloud_print::GetLastHResult();

  return S_OK;
}

}  // namespace

ServiceController::ServiceController()
    : name_(cloud_print::LoadLocalString(IDS_SERVICE_NAME)),
      command_line_(CommandLine::NO_PROGRAM) {
}

ServiceController::~ServiceController() {
}

HRESULT ServiceController::StartService() {
  ServiceHandle service;
  HRESULT hr = OpenService(name_, SERVICE_START| SERVICE_QUERY_STATUS,
                           &service);
  if (FAILED(hr))
    return hr;
  if (!::StartService(service, 0, NULL))
    return cloud_print::GetLastHResult();
  SERVICE_STATUS status = {0};
  while (::QueryServiceStatus(service, &status) &&
          status.dwCurrentState == SERVICE_START_PENDING) {
    Sleep(100);
  }
  return S_OK;
}

HRESULT ServiceController::StopService() {
  ServiceHandle service;
  HRESULT hr = OpenService(name_, SERVICE_STOP | SERVICE_QUERY_STATUS,
                           &service);
  if (FAILED(hr))
    return hr;
  SERVICE_STATUS status = {0};
  if (!::ControlService(service, SERVICE_CONTROL_STOP, &status))
    return cloud_print::GetLastHResult();
  while (::QueryServiceStatus(service, &status) &&
          status.dwCurrentState > SERVICE_STOPPED) {
    Sleep(500);
    ::ControlService(service, SERVICE_CONTROL_STOP, &status);
  }
  return S_OK;
}

base::FilePath ServiceController::GetBinary() const {
  base::FilePath service_path;
  CHECK(PathService::Get(base::FILE_EXE, &service_path));
  return service_path.DirName().Append(base::FilePath(kServiceExeName));
}

HRESULT ServiceController::InstallConnectorService(
    const base::string16& user,
    const base::string16& password,
    const base::FilePath& user_data_dir,
    bool enable_logging) {
  return InstallService(user, password, true, kServiceSwitch, user_data_dir,
                        enable_logging);
}

HRESULT ServiceController::InstallCheckService(
    const base::string16& user,
    const base::string16& password,
    const base::FilePath& user_data_dir) {
  return InstallService(user, password, false, kRequirementsSwitch,
                        user_data_dir, true);
}

HRESULT ServiceController::InstallService(const base::string16& user,
                                          const base::string16& password,
                                          bool auto_start,
                                          const std::string& run_switch,
                                          const base::FilePath& user_data_dir,
                                          bool enable_logging) {
  // TODO(vitalybuka): consider "lite" version if we don't want unregister
  // printers here.
  HRESULT hr = UninstallService();
  if (FAILED(hr))
    return hr;

  hr = UpdateRegistryAppId(true);
  if (FAILED(hr))
    return hr;

  base::FilePath service_path = GetBinary();
  if (!base::PathExists(service_path))
    return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  CommandLine command_line(service_path);
  command_line.AppendSwitch(run_switch);
  if (!user_data_dir.empty())
    command_line.AppendSwitchPath(switches::kUserDataDir, user_data_dir);
  if (enable_logging) {
    command_line.AppendSwitch(switches::kEnableLogging);
    command_line.AppendSwitchASCII(switches::kV, "1");
  }

  CopyChromeSwitchesFromCurrentProcess(&command_line);

  LocalSecurityPolicy local_security_policy;
  if (local_security_policy.Open()) {
    if (!local_security_policy.IsPrivilegeSet(user, kSeServiceLogonRight)) {
      LOG(WARNING) << "Setting " << kSeServiceLogonRight << " for " << user;
      if (!local_security_policy.SetPrivilege(user, kSeServiceLogonRight)) {
        LOG(ERROR) << "Failed to set" << kSeServiceLogonRight;
        LOG(ERROR) << "Make sure you can run the service as " << user << ".";
      }
    }
  } else {
    LOG(ERROR) << "Failed to open security policy.";
  }

  ServiceHandle scm;
  hr = OpenServiceManager(&scm);
  if (FAILED(hr))
    return hr;

  base::string16 display_name =
      cloud_print::LoadLocalString(IDS_SERVICE_DISPLAY_NAME);
  ServiceHandle service(
      ::CreateService(
          scm, name_.c_str(), display_name.c_str(), SERVICE_ALL_ACCESS,
          SERVICE_WIN32_OWN_PROCESS,
          auto_start ? SERVICE_AUTO_START : SERVICE_DEMAND_START,
          SERVICE_ERROR_NORMAL, command_line.GetCommandLineString().c_str(),
          NULL, NULL, NULL, user.empty() ? NULL : user.c_str(),
          password.empty() ? NULL : password.c_str()));

  if (!service.IsValid()) {
    LOG(ERROR) << "Failed to install service as " << user << ".";
    return cloud_print::GetLastHResult();
  }

  base::string16 description_string =
      cloud_print::LoadLocalString(IDS_SERVICE_DESCRIPTION);
  SERVICE_DESCRIPTION description = {0};
  description.lpDescription = const_cast<wchar_t*>(description_string.c_str());
  ::ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &description);

  return S_OK;
}

HRESULT ServiceController::UninstallService() {
  StopService();

  ServiceHandle service;
  OpenService(name_, SERVICE_STOP | DELETE, &service);
  HRESULT hr = S_FALSE;
  if (service) {
    if (!::DeleteService(service)) {
      LOG(ERROR) << "Failed to uninstall service";
      hr = cloud_print::GetLastHResult();
    }
  }
  UpdateRegistryAppId(false);
  return hr;
}

HRESULT ServiceController::UpdateBinaryPath() {
  UpdateState();
  ServiceController::State origina_state = state();
  if (origina_state < ServiceController::STATE_STOPPED)
    return S_FALSE;

  ServiceHandle service;
  HRESULT hr = OpenService(name_, SERVICE_CHANGE_CONFIG, &service);
  if (FAILED(hr))
    return hr;

  base::FilePath service_path = GetBinary();
  if (!base::PathExists(service_path))
    return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

  command_line_.SetProgram(service_path);
  if (!::ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
                             SERVICE_NO_CHANGE,
                             command_line_.GetCommandLineString().c_str(), NULL,
                             NULL, NULL, NULL, NULL, NULL)) {
    return cloud_print::GetLastHResult();
  }

  if (origina_state != ServiceController::STATE_RUNNING)
    return S_OK;

  hr = StopService();
  if (FAILED(hr))
    return hr;

  hr = StartService();
  if (FAILED(hr))
    return hr;

  return S_OK;
}

void ServiceController::UpdateState() {
  state_ = STATE_NOT_FOUND;
  user_.clear();
  is_logging_enabled_ = false;

  ServiceHandle service;
  HRESULT hr = OpenService(name_, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG,
                           &service);
  if (FAILED(hr))
    return;

  state_ = STATE_STOPPED;
  SERVICE_STATUS status = {0};
  if (::QueryServiceStatus(service, &status) &&
      status.dwCurrentState == SERVICE_RUNNING) {
    state_ = STATE_RUNNING;
  }

  DWORD config_size = 0;
  ::QueryServiceConfig(service, NULL, 0, &config_size);
  if (!config_size)
    return;

  std::vector<uint8> buffer(config_size, 0);
  QUERY_SERVICE_CONFIG* config =
      reinterpret_cast<QUERY_SERVICE_CONFIG*>(&buffer[0]);
  if (!::QueryServiceConfig(service, config, buffer.size(), &config_size) ||
      config_size != buffer.size()) {
    return;
  }

  command_line_ = CommandLine::FromString(config->lpBinaryPathName);
  if (!command_line_.HasSwitch(kServiceSwitch)) {
    state_ = STATE_NOT_FOUND;
    return;
  }
  is_logging_enabled_ = command_line_.HasSwitch(switches::kEnableLogging);
  user_ = config->lpServiceStartName;
}

bool ServiceController::is_logging_enabled() const {
  return command_line_.HasSwitch(switches::kEnableLogging);
}
