// Copyright (c) 2009 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.
//
// Implementation of a Windows event trace controller class.
#include "base/win/event_trace_controller.h"
#include "base/logging.h"

namespace base {
namespace win {

EtwTraceProperties::EtwTraceProperties() {
  memset(buffer_, 0, sizeof(buffer_));
  EVENT_TRACE_PROPERTIES* prop = get();

  prop->Wnode.BufferSize = sizeof(buffer_);
  prop->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  prop->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  prop->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) +
                            sizeof(wchar_t) * kMaxStringLen;
}

HRESULT EtwTraceProperties::SetLoggerName(const wchar_t* logger_name) {
  size_t len = wcslen(logger_name) + 1;
  if (kMaxStringLen < len)
    return E_INVALIDARG;

  memcpy(buffer_ + get()->LoggerNameOffset,
         logger_name,
         sizeof(wchar_t) * len);
  return S_OK;
}

HRESULT EtwTraceProperties::SetLoggerFileName(const wchar_t* logger_file_name) {
  size_t len = wcslen(logger_file_name) + 1;
  if (kMaxStringLen < len)
    return E_INVALIDARG;

  memcpy(buffer_ + get()->LogFileNameOffset,
         logger_file_name,
         sizeof(wchar_t) * len);
  return S_OK;
}

EtwTraceController::EtwTraceController() : session_(NULL) {
}

EtwTraceController::~EtwTraceController() {
  if (session_)
    Stop(NULL);
}

HRESULT EtwTraceController::Start(const wchar_t* session_name,
    EtwTraceProperties* prop) {
  DCHECK(NULL == session_ && session_name_.empty());
  EtwTraceProperties ignore;
  if (prop == NULL)
    prop = &ignore;

  HRESULT hr = Start(session_name, prop, &session_);
  if (SUCCEEDED(hr))
    session_name_ = session_name;

  return hr;
}

HRESULT EtwTraceController::StartFileSession(const wchar_t* session_name,
    const wchar_t* logfile_path, bool realtime) {
  DCHECK(NULL == session_ && session_name_.empty());

  EtwTraceProperties prop;
  prop.SetLoggerFileName(logfile_path);
  EVENT_TRACE_PROPERTIES& p = *prop.get();
  p.Wnode.ClientContext = 1;  // QPC timer accuracy.
  p.LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL;  // Sequential log.
  if (realtime)
    p.LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;

  p.MaximumFileSize = 100;  // 100M file size.
  p.FlushTimer = 30;  // 30 seconds flush lag.
  return Start(session_name, &prop);
}

HRESULT EtwTraceController::StartRealtimeSession(const wchar_t* session_name,
    size_t buffer_size) {
  DCHECK(NULL == session_ && session_name_.empty());
  EtwTraceProperties prop;
  EVENT_TRACE_PROPERTIES& p = *prop.get();
  p.LogFileMode = EVENT_TRACE_REAL_TIME_MODE | EVENT_TRACE_USE_PAGED_MEMORY;
  p.FlushTimer = 1;  // flush every second.
  p.BufferSize = 16;  // 16 K buffers.
  p.LogFileNameOffset = 0;
  return Start(session_name, &prop);
}

HRESULT EtwTraceController::EnableProvider(REFGUID provider, UCHAR level,
    ULONG flags) {
  ULONG error = ::EnableTrace(TRUE, flags, level, &provider, session_);
  return HRESULT_FROM_WIN32(error);
}

HRESULT EtwTraceController::DisableProvider(REFGUID provider) {
  ULONG error = ::EnableTrace(FALSE, 0, 0, &provider, session_);
  return HRESULT_FROM_WIN32(error);
}

HRESULT EtwTraceController::Stop(EtwTraceProperties* properties) {
  EtwTraceProperties ignore;
  if (properties == NULL)
    properties = &ignore;

  ULONG error = ::ControlTrace(session_, NULL, properties->get(),
    EVENT_TRACE_CONTROL_STOP);
  if (ERROR_SUCCESS != error)
    return HRESULT_FROM_WIN32(error);

  session_ = NULL;
  session_name_.clear();
  return S_OK;
}

HRESULT EtwTraceController::Flush(EtwTraceProperties* properties) {
  EtwTraceProperties ignore;
  if (properties == NULL)
    properties = &ignore;

  ULONG error = ::ControlTrace(session_, NULL, properties->get(),
                               EVENT_TRACE_CONTROL_FLUSH);
  if (ERROR_SUCCESS != error)
    return HRESULT_FROM_WIN32(error);

  return S_OK;
}

HRESULT EtwTraceController::Start(const wchar_t* session_name,
    EtwTraceProperties* properties, TRACEHANDLE* session_handle) {
  DCHECK(properties != NULL);
  ULONG err = ::StartTrace(session_handle, session_name, properties->get());
  return HRESULT_FROM_WIN32(err);
}

HRESULT EtwTraceController::Query(const wchar_t* session_name,
    EtwTraceProperties* properties) {
  ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
                             EVENT_TRACE_CONTROL_QUERY);
  return HRESULT_FROM_WIN32(err);
};

HRESULT EtwTraceController::Update(const wchar_t* session_name,
    EtwTraceProperties* properties) {
  DCHECK(properties != NULL);
  ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
                             EVENT_TRACE_CONTROL_UPDATE);
  return HRESULT_FROM_WIN32(err);
}

HRESULT EtwTraceController::Stop(const wchar_t* session_name,
    EtwTraceProperties* properties) {
  DCHECK(properties != NULL);
  ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
                             EVENT_TRACE_CONTROL_STOP);
  return HRESULT_FROM_WIN32(err);
}

HRESULT EtwTraceController::Flush(const wchar_t* session_name,
    EtwTraceProperties* properties) {
  DCHECK(properties != NULL);
  ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
                             EVENT_TRACE_CONTROL_FLUSH);
  return HRESULT_FROM_WIN32(err);
}

}  // namespace win
}  // namespace base
