// Copyright 2016 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/client/client_telemetry_logger.h"

#include "base/format_macros.h"
#include "base/logging.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "remoting/base/telemetry_log_writer.h"

#if defined(OS_ANDROID)
#include <android/log.h>
#endif  // OS_ANDROID

namespace {

const char kSessionIdAlphabet[] =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
const int kSessionIdLength = 20;
const int kMaxSessionIdAgeDays = 1;

}  // namespace

namespace remoting {

struct ClientTelemetryLogger::HostInfo {
  const std::string host_version;
  const ChromotingEvent::Os host_os;
  const std::string host_os_version;
};

ClientTelemetryLogger::ClientTelemetryLogger(
    ChromotingEventLogWriter* log_writer,
    ChromotingEvent::Mode mode)
    : mode_(mode), log_writer_(log_writer), weak_factory_(this) {
  thread_checker_.DetachFromThread();
}

ClientTelemetryLogger::~ClientTelemetryLogger() {
  DCHECK(thread_checker_.CalledOnValidThread());
}

void ClientTelemetryLogger::SetAuthMethod(
    ChromotingEvent::AuthMethod auth_method) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_NE(ChromotingEvent::AuthMethod::NOT_SET, auth_method);
  auth_method_ = auth_method;
}

void ClientTelemetryLogger::SetHostInfo(const std::string& host_version,
                                        ChromotingEvent::Os host_os,
                                        const std::string& host_os_version) {
  DCHECK(thread_checker_.CalledOnValidThread());
  host_info_.reset(new HostInfo{host_version, host_os, host_os_version});
}

void ClientTelemetryLogger::SetTransportRoute(
    const protocol::TransportRoute& route) {
  DCHECK(thread_checker_.CalledOnValidThread());
  transport_route_ = std::make_unique<protocol::TransportRoute>(route);
}

void ClientTelemetryLogger::LogSessionStateChange(
    ChromotingEvent::SessionState state,
    ChromotingEvent::ConnectionError error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  RefreshSessionIdIfOutdated();
  if (session_start_time_.is_null()) {
    session_start_time_ = base::TimeTicks::Now();
  }

  ChromotingEvent event =
      ClientTelemetryLogger::MakeSessionStateChangeEvent(state, error);

  const base::Value* previous_state =
      current_session_state_event_.GetValue(ChromotingEvent::kSessionStateKey);
  if (previous_state) {
    event.SetInteger(ChromotingEvent::kPreviousSessionStateKey,
                     previous_state->GetInt());
  }

  log_writer_->Log(event);
  current_session_state_event_ = std::move(event);

  if (ChromotingEvent::IsEndOfSession(state)) {
    session_id_.clear();
    session_start_time_ = base::TimeTicks();
  }
}

void ClientTelemetryLogger::LogStatistics(
    const protocol::PerformanceTracker& perf_tracker) {
  DCHECK(thread_checker_.CalledOnValidThread());
  RefreshSessionIdIfOutdated();

  PrintLogStatistics(perf_tracker);

  ChromotingEvent event = MakeStatsEvent(perf_tracker);
  log_writer_->Log(event);
}

base::WeakPtr<ClientTelemetryLogger> ClientTelemetryLogger::GetWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

void ClientTelemetryLogger::PrintLogStatistics(
    const protocol::PerformanceTracker& perf_tracker) {
#if defined(OS_ANDROID)
  __android_log_print(
      ANDROID_LOG_INFO, "stats",
#else
  VLOG(0) << base::StringPrintf(
#endif  // OS_ANDROID
      "Bandwidth:%.0f FrameRate:%.1f;"
      " (Avg, Max) Capture:%.1f, %" PRId64 " Encode:%.1f, %" PRId64
      " Decode:%.1f, %" PRId64 " Render:%.1f, %" PRId64 " RTL:%.0f, %" PRId64,
      perf_tracker.video_bandwidth(), perf_tracker.video_frame_rate(),
      perf_tracker.video_capture_ms().Average(),
      perf_tracker.video_capture_ms().Max(),
      perf_tracker.video_encode_ms().Average(),
      perf_tracker.video_encode_ms().Max(),
      perf_tracker.video_decode_ms().Average(),
      perf_tracker.video_decode_ms().Max(),
      perf_tracker.video_paint_ms().Average(),
      perf_tracker.video_paint_ms().Max(),
      perf_tracker.round_trip_ms().Average(),
      perf_tracker.round_trip_ms().Max());
}

void ClientTelemetryLogger::SetSessionIdGenerationTimeForTest(
    base::TimeTicks gen_time) {
  session_id_generation_time_ = gen_time;
}

// static
ChromotingEvent::SessionState ClientTelemetryLogger::TranslateState(
    protocol::ConnectionToHost::State current_state,
    protocol::ConnectionToHost::State previous_state) {
  switch (current_state) {
    case protocol::ConnectionToHost::State::INITIALIZING:
      return ChromotingEvent::SessionState::INITIALIZING;
    case protocol::ConnectionToHost::State::CONNECTING:
      return ChromotingEvent::SessionState::CONNECTING;
    case protocol::ConnectionToHost::State::AUTHENTICATED:
      return ChromotingEvent::SessionState::AUTHENTICATED;
    case protocol::ConnectionToHost::State::CONNECTED:
      return ChromotingEvent::SessionState::CONNECTED;
    case protocol::ConnectionToHost::State::FAILED:
      return previous_state == protocol::ConnectionToHost::State::CONNECTED
                 ? ChromotingEvent::SessionState::CONNECTION_DROPPED
                 : ChromotingEvent::SessionState::CONNECTION_FAILED;
    case protocol::ConnectionToHost::State::CLOSED:
      return ChromotingEvent::SessionState::CLOSED;
    default:
      NOTREACHED();
      return ChromotingEvent::SessionState::UNKNOWN;
  }
}

// static
ChromotingEvent::ConnectionError ClientTelemetryLogger::TranslateError(
    protocol::ErrorCode error) {
  switch (error) {
    case protocol::OK:
      return ChromotingEvent::ConnectionError::NONE;
    case protocol::PEER_IS_OFFLINE:
      return ChromotingEvent::ConnectionError::HOST_OFFLINE;
    case protocol::SESSION_REJECTED:
      return ChromotingEvent::ConnectionError::SESSION_REJECTED;
    case protocol::INCOMPATIBLE_PROTOCOL:
      return ChromotingEvent::ConnectionError::INCOMPATIBLE_PROTOCOL;
    case protocol::AUTHENTICATION_FAILED:
      return ChromotingEvent::ConnectionError::AUTHENTICATION_FAILED;
    case protocol::INVALID_ACCOUNT:
      return ChromotingEvent::ConnectionError::INVALID_ACCOUNT;
    case protocol::CHANNEL_CONNECTION_ERROR:
      return ChromotingEvent::ConnectionError::P2P_FAILURE;
    case protocol::SIGNALING_ERROR:
      return ChromotingEvent::ConnectionError::NETWORK_FAILURE;
    case protocol::SIGNALING_TIMEOUT:
      return ChromotingEvent::ConnectionError::NETWORK_FAILURE;
    case protocol::HOST_OVERLOAD:
      return ChromotingEvent::ConnectionError::HOST_OVERLOAD;
    case protocol::MAX_SESSION_LENGTH:
      return ChromotingEvent::ConnectionError::MAX_SESSION_LENGTH;
    case protocol::HOST_CONFIGURATION_ERROR:
      return ChromotingEvent::ConnectionError::HOST_CONFIGURATION_ERROR;
    case protocol::UNKNOWN_ERROR:
      return ChromotingEvent::ConnectionError::UNKNOWN_ERROR;
    default:
      NOTREACHED();
      return ChromotingEvent::ConnectionError::UNEXPECTED;
  }
}

// static
ChromotingEvent::ConnectionType ClientTelemetryLogger::TranslateConnectionType(
    protocol::TransportRoute::RouteType type) {
  switch (type) {
    case protocol::TransportRoute::DIRECT:
      return ChromotingEvent::ConnectionType::DIRECT;
    case protocol::TransportRoute::STUN:
      return ChromotingEvent::ConnectionType::STUN;
    case protocol::TransportRoute::RELAY:
      return ChromotingEvent::ConnectionType::RELAY;
    default:
      NOTREACHED();
      return ChromotingEvent::ConnectionType::DIRECT;
  }
}

void ClientTelemetryLogger::FillEventContext(ChromotingEvent* event) const {
  event->SetEnum(ChromotingEvent::kModeKey, mode_);
  event->SetEnum(ChromotingEvent::kRoleKey, ChromotingEvent::Role::CLIENT);
  if (auth_method_ != ChromotingEvent::AuthMethod::NOT_SET) {
    event->SetEnum(ChromotingEvent::kAuthMethodKey, auth_method_);
  }
  if (host_info_) {
    event->SetString(ChromotingEvent::kHostVersionKey,
                     host_info_->host_version);
    event->SetEnum(ChromotingEvent::kHostOsKey, host_info_->host_os);
    event->SetString(ChromotingEvent::kHostOsVersionKey,
                     host_info_->host_os_version);
  }
  if (transport_route_) {
    ChromotingEvent::ConnectionType connection_type =
        TranslateConnectionType(transport_route_->type);
    event->SetEnum(ChromotingEvent::kConnectionTypeKey, connection_type);
  }
  event->AddSystemInfo();
  if (!session_id_.empty()) {
    event->SetString(ChromotingEvent::kSessionIdKey, session_id_);
  }
  if (!session_start_time_.is_null()) {
    int session_duration =
        (base::TimeTicks::Now() - session_start_time_).InSeconds();
    event->SetInteger(ChromotingEvent::kSessionDurationKey, session_duration);
  }
}

void ClientTelemetryLogger::GenerateSessionId() {
  session_id_.resize(kSessionIdLength);
  for (int i = 0; i < kSessionIdLength; i++) {
    const int alphabet_size = arraysize(kSessionIdAlphabet) - 1;
    session_id_[i] = kSessionIdAlphabet[base::RandGenerator(alphabet_size)];
  }
  session_id_generation_time_ = base::TimeTicks::Now();
}

void ClientTelemetryLogger::RefreshSessionIdIfOutdated() {
  if (session_id_.empty()) {
    GenerateSessionId();
    return;
  }

  base::TimeDelta max_age = base::TimeDelta::FromDays(kMaxSessionIdAgeDays);
  if (base::TimeTicks::Now() - session_id_generation_time_ > max_age) {
    // Log the old session ID.
    ChromotingEvent event = MakeSessionIdOldEvent();
    log_writer_->Log(event);

    // Generate a new session ID.
    GenerateSessionId();

    // Log the new session ID.
    ChromotingEvent new_id_event = MakeSessionIdNewEvent();
    log_writer_->Log(new_id_event);
  }
}

ChromotingEvent ClientTelemetryLogger::MakeStatsEvent(
    const protocol::PerformanceTracker& perf_tracker) {
  ChromotingEvent event(ChromotingEvent::Type::CONNECTION_STATISTICS);
  FillEventContext(&event);

  event.SetDouble(ChromotingEvent::kVideoBandwidthKey,
                  perf_tracker.video_bandwidth());
  event.SetDouble(ChromotingEvent::kCaptureLatencyKey,
                  perf_tracker.video_capture_ms().Average());
  event.SetDouble(ChromotingEvent::kEncodeLatencyKey,
                  perf_tracker.video_encode_ms().Average());
  event.SetDouble(ChromotingEvent::kDecodeLatencyKey,
                  perf_tracker.video_decode_ms().Average());
  event.SetDouble(ChromotingEvent::kRenderLatencyKey,
                  perf_tracker.video_paint_ms().Average());
  event.SetDouble(ChromotingEvent::kRoundtripLatencyKey,
                  perf_tracker.round_trip_ms().Average());
  event.SetDouble(ChromotingEvent::kMaxCaptureLatencyKey,
                  perf_tracker.video_capture_ms().Max());
  event.SetDouble(ChromotingEvent::kMaxEncodeLatencyKey,
                  perf_tracker.video_encode_ms().Max());
  event.SetDouble(ChromotingEvent::kMaxDecodeLatencyKey,
                  perf_tracker.video_decode_ms().Max());
  event.SetDouble(ChromotingEvent::kMaxRenderLatencyKey,
                  perf_tracker.video_paint_ms().Max());
  event.SetDouble(ChromotingEvent::kMaxRoundtripLatencyKey,
                  perf_tracker.round_trip_ms().Max());

  return event;
}

ChromotingEvent ClientTelemetryLogger::MakeSessionStateChangeEvent(
    ChromotingEvent::SessionState state,
    ChromotingEvent::ConnectionError error) {
  ChromotingEvent event(ChromotingEvent::Type::SESSION_STATE);
  FillEventContext(&event);
  event.SetEnum(ChromotingEvent::kSessionStateKey, state);
  event.SetEnum(ChromotingEvent::kConnectionErrorKey, error);
  return event;
}

ChromotingEvent ClientTelemetryLogger::MakeSessionIdOldEvent() {
  ChromotingEvent event(ChromotingEvent::Type::SESSION_ID_OLD);
  FillEventContext(&event);
  return event;
}

ChromotingEvent ClientTelemetryLogger::MakeSessionIdNewEvent() {
  ChromotingEvent event(ChromotingEvent::Type::SESSION_ID_NEW);
  FillEventContext(&event);
  return event;
}

}  // namespace remoting
