// Copyright (c) 2012 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 "remoting/host/usage_stats_consent.h"

#include <windows.h>
#include <string>

#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/win/registry.h"
#include "remoting/host/win/omaha.h"

namespace {

// The following strings are used to construct the registry key names where
// we record whether the user has consented to crash dump collection.
// the user's consent to collect crash dumps is recorded.
const wchar_t kOmahaClientStateKeyFormat[] =
    L"Software\\Google\\Update\\%ls\\%ls";
const wchar_t kOmahaClientState[] = L"ClientState";
const wchar_t kOmahaClientStateMedium[] = L"ClientStateMedium";
const wchar_t kOmahaUsagestatsValue[] = L"usagestats";

LONG ReadUsageStatsValue(const wchar_t* state_key, DWORD* usagestats_out) {
  // presubmit: allow wstring
  std::wstring client_state = base::StringPrintf(kOmahaClientStateKeyFormat,
                                                 state_key,
                                                 remoting::kHostOmahaAppid);
  base::win::RegKey key;
  LONG result = key.Open(HKEY_LOCAL_MACHINE, client_state.c_str(), KEY_READ);
  if (result != ERROR_SUCCESS) {
    return result;
  }

  return key.ReadValueDW(kOmahaUsagestatsValue, usagestats_out);
}

}  // namespace

namespace remoting {

bool GetUsageStatsConsent(bool* allowed, bool* set_by_policy) {
  // TODO(alexeypa): report whether the consent is set by policy once
  // supported.
  *set_by_policy = false;

  // The user's consent to collect crash dumps is recored as the "usagestats"
  // value in the ClientState or ClientStateMedium key. Probe
  // the ClientStateMedium key first.
  DWORD value = 0;
  if (ReadUsageStatsValue(kOmahaClientStateMedium, &value) == ERROR_SUCCESS) {
    *allowed = value != 0;
    return true;
  }
  if (ReadUsageStatsValue(kOmahaClientState, &value) == ERROR_SUCCESS) {
    *allowed = value != 0;
    return true;
  }

  // We do not log the error code here because the logging hasn't been
  // initialized yet.
  return false;
}

bool IsUsageStatsAllowed() {
  bool allowed;
  bool set_by_policy;
  return GetUsageStatsConsent(&allowed, &set_by_policy) && allowed;
}

bool SetUsageStatsConsent(bool allowed) {
  DWORD value = allowed;
  // presubmit: allow wstring
  std::wstring client_state = base::StringPrintf(kOmahaClientStateKeyFormat,
                                                 kOmahaClientStateMedium,
                                                 kHostOmahaAppid);
  base::win::RegKey key;
  LONG result = key.Create(HKEY_LOCAL_MACHINE, client_state.c_str(),
                           KEY_SET_VALUE);
  if (result == ERROR_SUCCESS) {
    result = key.WriteValue(kOmahaUsagestatsValue, value);
    if (result == ERROR_SUCCESS) {
      return true;
    }
  }

  PLOG(ERROR) << "Failed to record the user's consent to crash dump reporting";
  return false;
}

}  // namespace remoting
