// Copyright 2014 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 "sky/viewer/platform/platform_impl.h"

#include <cmath>

#include "base/debug/trace_event.h"
#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "mojo/public/cpp/application/application_impl.h"
#include "net/base/data_url.h"
#include "net/base/mime_util.h"
#include "net/base/net_errors.h"
#include "sky/engine/public/platform/WebConvertableToTraceFormat.h"
#include "sky/viewer/platform/weburlloader_impl.h"

namespace sky {
namespace {

class ConvertableToTraceFormatWrapper
    : public base::debug::ConvertableToTraceFormat {
 public:
  explicit ConvertableToTraceFormatWrapper(
      const blink::WebConvertableToTraceFormat& convertable)
      : convertable_(convertable) {}
  virtual void AppendAsTraceFormat(std::string* out) const override {
    *out += convertable_.asTraceFormat().utf8();
  }

 private:
  virtual ~ConvertableToTraceFormatWrapper() {}

  blink::WebConvertableToTraceFormat convertable_;
};

}  // namespace

PlatformImpl::PlatformImpl(mojo::ApplicationImpl* app)
    : main_loop_(base::MessageLoop::current()),
      main_thread_task_runner_(base::MessageLoop::current()->task_runner()),
      shared_timer_func_(NULL),
      shared_timer_fire_time_(0.0),
      shared_timer_fire_time_was_set_while_suspended_(false),
      shared_timer_suspended_(0) {
  app->ConnectToService("mojo:network_service", &network_service_);

  mojo::CookieStorePtr cookie_store;
  network_service_->GetCookieStore(GetProxy(&cookie_store));
}

PlatformImpl::~PlatformImpl() {
}

blink::WebString PlatformImpl::defaultLocale() {
  return blink::WebString::fromUTF8("en-US");
}

double PlatformImpl::currentTime() {
  return base::Time::Now().ToDoubleT();
}

double PlatformImpl::monotonicallyIncreasingTime() {
  return base::TimeTicks::Now().ToInternalValue() /
      static_cast<double>(base::Time::kMicrosecondsPerSecond);
}

void PlatformImpl::setSharedTimerFiredFunction(void (*func)()) {
  shared_timer_func_ = func;
}

void PlatformImpl::setSharedTimerFireInterval(
    double interval_seconds) {
  shared_timer_fire_time_ = interval_seconds + monotonicallyIncreasingTime();
  if (shared_timer_suspended_) {
    shared_timer_fire_time_was_set_while_suspended_ = true;
    return;
  }

  // By converting between double and int64 representation, we run the risk
  // of losing precision due to rounding errors. Performing computations in
  // microseconds reduces this risk somewhat. But there still is the potential
  // of us computing a fire time for the timer that is shorter than what we
  // need.
  // As the event loop will check event deadlines prior to actually firing
  // them, there is a risk of needlessly rescheduling events and of
  // needlessly looping if sleep times are too short even by small amounts.
  // This results in measurable performance degradation unless we use ceil() to
  // always round up the sleep times.
  int64 interval = static_cast<int64>(
      ceil(interval_seconds * base::Time::kMillisecondsPerSecond)
      * base::Time::kMicrosecondsPerMillisecond);

  if (interval < 0)
    interval = 0;

  shared_timer_.Stop();
  shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval),
                      this, &PlatformImpl::DoTimeout);
}

void PlatformImpl::stopSharedTimer() {
  shared_timer_.Stop();
}

base::SingleThreadTaskRunner* PlatformImpl::mainThreadTaskRunner() {
  return main_thread_task_runner_.get();
}

mojo::NetworkService* PlatformImpl::networkService() {
  return network_service_.get();
}

blink::WebURLLoader* PlatformImpl::createURLLoader() {
  return new WebURLLoaderImpl(network_service_.get());
}

blink::WebURLError PlatformImpl::cancelledError(const blink::WebURL& url)
    const {
  blink::WebURLError error;
  error.domain = blink::WebString::fromUTF8(net::kErrorDomain);
  error.reason = net::ERR_ABORTED;
  error.unreachableURL = url;
  error.staleCopyInCache = false;
  error.isCancellation = true;
  return error;
}

const unsigned char* PlatformImpl::getTraceCategoryEnabledFlag(
    const char* category_group) {
  return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group);
}

long* PlatformImpl::getTraceSamplingState(const unsigned thread_bucket) {
  switch (thread_bucket) {
    case 0:
      return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(0));
    case 1:
      return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(1));
    case 2:
      return reinterpret_cast<long*>(&TRACE_EVENT_API_THREAD_BUCKET(2));
    default:
      NOTREACHED() << "Unknown thread bucket type.";
  }
  return NULL;
}

COMPILE_ASSERT(
    sizeof(blink::Platform::TraceEventHandle) ==
        sizeof(base::debug::TraceEventHandle),
    TraceEventHandle_types_must_be_same_size);

blink::Platform::TraceEventHandle PlatformImpl::addTraceEvent(
    char phase,
    const unsigned char* category_group_enabled,
    const char* name,
    unsigned long long id,
    int num_args,
    const char** arg_names,
    const unsigned char* arg_types,
    const unsigned long long* arg_values,
    unsigned char flags) {
  base::debug::TraceEventHandle handle = TRACE_EVENT_API_ADD_TRACE_EVENT(
      phase, category_group_enabled, name, id,
      num_args, arg_names, arg_types, arg_values, NULL, flags);
  blink::Platform::TraceEventHandle result;
  memcpy(&result, &handle, sizeof(result));
  return result;
}

blink::Platform::TraceEventHandle PlatformImpl::addTraceEvent(
    char phase,
    const unsigned char* category_group_enabled,
    const char* name,
    unsigned long long id,
    int num_args,
    const char** arg_names,
    const unsigned char* arg_types,
    const unsigned long long* arg_values,
    const blink::WebConvertableToTraceFormat* convertable_values,
    unsigned char flags) {
  scoped_refptr<base::debug::ConvertableToTraceFormat> convertable_wrappers[2];
  if (convertable_values) {
    size_t size = std::min(static_cast<size_t>(num_args),
                           arraysize(convertable_wrappers));
    for (size_t i = 0; i < size; ++i) {
      if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
        convertable_wrappers[i] =
            new ConvertableToTraceFormatWrapper(convertable_values[i]);
      }
    }
  }
  base::debug::TraceEventHandle handle =
      TRACE_EVENT_API_ADD_TRACE_EVENT(phase,
                                      category_group_enabled,
                                      name,
                                      id,
                                      num_args,
                                      arg_names,
                                      arg_types,
                                      arg_values,
                                      convertable_wrappers,
                                      flags);
  blink::Platform::TraceEventHandle result;
  memcpy(&result, &handle, sizeof(result));
  return result;
}

void PlatformImpl::updateTraceEventDuration(
    const unsigned char* category_group_enabled,
    const char* name,
    TraceEventHandle handle) {
  base::debug::TraceEventHandle traceEventHandle;
  memcpy(&traceEventHandle, &handle, sizeof(handle));
  TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
      category_group_enabled, name, traceEventHandle);
}

}  // namespace sky
