// 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 "ppapi/proxy/flash_resource.h"

#include <stddef.h>

#include <cmath>

#include "base/containers/mru_cache.h"
#include "base/debug/crash_logging.h"
#include "base/lazy_instance.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_flash.h"
#include "ppapi/c/trusted/ppb_browser_font_trusted.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/serialized_structs.h"
#include "ppapi/shared_impl/ppapi_preferences.h"
#include "ppapi/shared_impl/scoped_pp_var.h"
#include "ppapi/shared_impl/time_conversion.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_url_request_info_api.h"

using ppapi::thunk::EnterResourceNoLock;

namespace ppapi {
namespace proxy {

namespace {

struct LocalTimeZoneOffsetEntry {
  base::TimeTicks expiration;
  double offset;
};

class LocalTimeZoneOffsetCache
    : public base::MRUCache<PP_Time, LocalTimeZoneOffsetEntry> {
 public:
  LocalTimeZoneOffsetCache()
      : base::MRUCache<PP_Time, LocalTimeZoneOffsetEntry>(kCacheSize) {}
 private:
  static const size_t kCacheSize = 100;
};

base::LazyInstance<LocalTimeZoneOffsetCache>::Leaky
    g_local_time_zone_offset_cache = LAZY_INSTANCE_INITIALIZER;

} //  namespace

FlashResource::FlashResource(Connection connection,
                             PP_Instance instance,
                             PluginDispatcher* plugin_dispatcher)
    : PluginResource(connection, instance),
      plugin_dispatcher_(plugin_dispatcher) {
  SendCreate(RENDERER, PpapiHostMsg_Flash_Create());
  SendCreate(BROWSER, PpapiHostMsg_Flash_Create());
}

FlashResource::~FlashResource() {
}

thunk::PPB_Flash_Functions_API* FlashResource::AsPPB_Flash_Functions_API() {
  return this;
}

PP_Var FlashResource::GetProxyForURL(PP_Instance instance,
                                     const std::string& url) {
  std::string proxy;
  int32_t result = SyncCall<PpapiPluginMsg_Flash_GetProxyForURLReply>(RENDERER,
      PpapiHostMsg_Flash_GetProxyForURL(url), &proxy);

  if (result == PP_OK)
    return StringVar::StringToPPVar(proxy);
  return PP_MakeUndefined();
}

void FlashResource::UpdateActivity(PP_Instance instance) {
  Post(BROWSER, PpapiHostMsg_Flash_UpdateActivity());
}

PP_Bool FlashResource::SetCrashData(PP_Instance instance,
                                    PP_FlashCrashKey key,
                                    PP_Var value) {
  StringVar* url_string_var(StringVar::FromPPVar(value));
  if (!url_string_var)
    return PP_FALSE;
  switch (key) {
    case PP_FLASHCRASHKEY_URL: {
      PluginGlobals::Get()->SetActiveURL(url_string_var->value());
      return PP_TRUE;
    }
    case PP_FLASHCRASHKEY_RESOURCE_URL: {
      base::debug::SetCrashKeyValue("subresource_url", url_string_var->value());
      return PP_TRUE;
    }
  }
  return PP_FALSE;
}

double FlashResource::GetLocalTimeZoneOffset(PP_Instance instance,
                                             PP_Time t) {
  LocalTimeZoneOffsetCache& cache = g_local_time_zone_offset_cache.Get();

  // Get the minimum PP_Time value that shares the same minute as |t|.
  // Use cached offset if cache hasn't expired and |t| is in the same minute as
  // the time for the cached offset (assume offsets change on minute
  // boundaries).
  PP_Time t_minute_base = floor(t / 60.0) * 60.0;
  LocalTimeZoneOffsetCache::iterator iter = cache.Get(t_minute_base);
  base::TimeTicks now = base::TimeTicks::Now();
  if (iter != cache.end() && now < iter->second.expiration)
    return iter->second.offset;

  // Cache the local offset for ten seconds, since it's slow on XP and Linux.
  // Note that TimeTicks does not continue counting across sleep/resume on all
  // platforms. This may be acceptable for 10 seconds, but if in the future this
  // is changed to one minute or more, then we should consider using base::Time.
  const int64_t kMaxCachedLocalOffsetAgeInSeconds = 10;
  base::TimeDelta expiration_delta =
      base::TimeDelta::FromSeconds(kMaxCachedLocalOffsetAgeInSeconds);

  LocalTimeZoneOffsetEntry cache_entry;
  cache_entry.expiration = now + expiration_delta;
  cache_entry.offset = 0.0;

  // We can't do the conversion here on Linux because the localtime calls
  // require filesystem access prohibited by the sandbox.
  // TODO(shess): Figure out why OSX needs the access, the sandbox warmup should
  // handle it.  http://crbug.com/149006
#if defined(OS_LINUX) || defined(OS_MACOSX)
  int32_t result = SyncCall<PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply>(
      BROWSER,
      PpapiHostMsg_Flash_GetLocalTimeZoneOffset(PPTimeToTime(t)),
      &cache_entry.offset);
  if (result != PP_OK)
    cache_entry.offset = 0.0;
#else
  cache_entry.offset = PPGetLocalTimeZoneOffset(PPTimeToTime(t));
#endif

  cache.Put(t_minute_base, cache_entry);
  return cache_entry.offset;
}

PP_Var FlashResource::GetSetting(PP_Instance instance,
                                 PP_FlashSetting setting) {
  switch (setting) {
    case PP_FLASHSETTING_3DENABLED:
      return PP_MakeBool(PP_FromBool(
          plugin_dispatcher_->preferences().is_3d_supported));
    case PP_FLASHSETTING_INCOGNITO:
      return PP_MakeBool(PP_FromBool(plugin_dispatcher_->incognito()));
    case PP_FLASHSETTING_STAGE3DENABLED:
      return PP_MakeBool(PP_FromBool(
          plugin_dispatcher_->preferences().is_stage3d_supported));
    case PP_FLASHSETTING_STAGE3DBASELINEENABLED:
      return PP_MakeBool(PP_FromBool(
          plugin_dispatcher_->preferences().is_stage3d_baseline_supported));
    case PP_FLASHSETTING_LANGUAGE:
      return StringVar::StringToPPVar(
          PluginGlobals::Get()->GetUILanguage());
    case PP_FLASHSETTING_NUMCORES:
      return PP_MakeInt32(
          plugin_dispatcher_->preferences().number_of_cpu_cores);
    case PP_FLASHSETTING_LSORESTRICTIONS: {
      int32_t restrictions;
      int32_t result =
          SyncCall<PpapiPluginMsg_Flash_GetLocalDataRestrictionsReply>(BROWSER,
              PpapiHostMsg_Flash_GetLocalDataRestrictions(), &restrictions);
      if (result != PP_OK)
        return PP_MakeInt32(PP_FLASHLSORESTRICTIONS_NONE);
      return PP_MakeInt32(restrictions);
    }
  }
  return PP_MakeUndefined();
}

void FlashResource::SetInstanceAlwaysOnTop(PP_Instance instance,
                                           PP_Bool on_top) {
  Post(RENDERER, PpapiHostMsg_Flash_SetInstanceAlwaysOnTop(PP_ToBool(on_top)));
}

PP_Bool FlashResource::DrawGlyphs(
    PP_Instance instance,
    PP_Resource pp_image_data,
    const PP_BrowserFont_Trusted_Description* font_desc,
    uint32_t color,
    const PP_Point* position,
    const PP_Rect* clip,
    const float transformation[3][3],
    PP_Bool allow_subpixel_aa,
    uint32_t glyph_count,
    const uint16_t glyph_indices[],
    const PP_Point glyph_advances[]) {
  EnterResourceNoLock<thunk::PPB_ImageData_API> enter(pp_image_data, true);
  if (enter.failed())
    return PP_FALSE;
  // The instance parameter isn't strictly necessary but we check that it
  // matches anyway.
  if (enter.resource()->pp_instance() != instance)
    return PP_FALSE;

  PPBFlash_DrawGlyphs_Params params;
  params.image_data = enter.resource()->host_resource();
  params.font_desc.SetFromPPBrowserFontDescription(*font_desc);
  params.color = color;
  params.position = *position;
  params.clip = *clip;
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++)
      params.transformation[i][j] = transformation[i][j];
  }
  params.allow_subpixel_aa = allow_subpixel_aa;

  params.glyph_indices.insert(params.glyph_indices.begin(),
                              &glyph_indices[0],
                              &glyph_indices[glyph_count]);
  params.glyph_advances.insert(params.glyph_advances.begin(),
                               &glyph_advances[0],
                               &glyph_advances[glyph_count]);

  // This has to be synchronous because the caller may want to composite on
  // top of the resulting text after the call is complete.
  int32_t result = SyncCall<IPC::Message>(RENDERER,
      PpapiHostMsg_Flash_DrawGlyphs(params));
  return PP_FromBool(result == PP_OK);
}

int32_t FlashResource::Navigate(PP_Instance instance,
                                PP_Resource request_info,
                                const char* target,
                                PP_Bool from_user_action) {
  EnterResourceNoLock<thunk::PPB_URLRequestInfo_API> enter(request_info,
                                                                  true);
  if (enter.failed())
    return PP_ERROR_BADRESOURCE;
  return SyncCall<IPC::Message>(RENDERER, PpapiHostMsg_Flash_Navigate(
      enter.object()->GetData(), target, PP_ToBool(from_user_action)));
}

PP_Bool FlashResource::IsRectTopmost(PP_Instance instance,
                                     const PP_Rect* rect) {
  int32_t result = SyncCall<IPC::Message>(RENDERER,
      PpapiHostMsg_Flash_IsRectTopmost(*rect));
  return PP_FromBool(result == PP_OK);
}

void FlashResource::InvokePrinting(PP_Instance instance) {
  Post(RENDERER, PpapiHostMsg_Flash_InvokePrinting());
}

}  // namespace proxy
}  // namespace ppapi
