// Copyright (c) 2011 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 "chrome/renderer/plugins/plugin_uma.h"

#include <algorithm>
#include <cstring>

#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "content/public/common/content_constants.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"

namespace {

// String we will use to convert mime type to plugin type.
const char kWindowsMediaPlayerType[] = "application/x-mplayer2";
const char kSilverlightTypePrefix[] = "application/x-silverlight";
const char kRealPlayerTypePrefix[] = "audio/x-pn-realaudio";
const char kJavaTypeSubstring[] = "application/x-java-applet";
const char kQuickTimeType[] = "video/quicktime";

// Arrays containing file extensions connected with specific plugins.
// Note: THE ARRAYS MUST BE SORTED BECAUSE BINARY SEARCH IS USED ON THEM!
const char* kWindowsMediaPlayerExtensions[] = {".asx"};

const char* kRealPlayerExtensions[] = {".ra",  ".ram", ".rm",
                                       ".rmm", ".rmp", ".rpm"};

const char* kQuickTimeExtensions[] = {".moov", ".mov", ".qif",
                                      ".qt",   ".qti", ".qtif"};

const char* kShockwaveFlashExtensions[] = {".spl", ".swf"};

}  // namespace.

class UMASenderImpl : public PluginUMAReporter::UMASender {
  virtual void SendPluginUMA(
      PluginUMAReporter::ReportType report_type,
      PluginUMAReporter::PluginType plugin_type) OVERRIDE;
};

void UMASenderImpl::SendPluginUMA(PluginUMAReporter::ReportType report_type,
                                  PluginUMAReporter::PluginType plugin_type) {
  // UMA_HISTOGRAM_ENUMERATION requires constant histogram name. Use string
  // constants explicitly instead of trying to use variables for names.
  switch (report_type) {
    case PluginUMAReporter::MISSING_PLUGIN:
      UMA_HISTOGRAM_ENUMERATION("Plugin.MissingPlugins",
                                plugin_type,
                                PluginUMAReporter::PLUGIN_TYPE_MAX);
      break;
    case PluginUMAReporter::DISABLED_PLUGIN:
      UMA_HISTOGRAM_ENUMERATION("Plugin.DisabledPlugins",
                                plugin_type,
                                PluginUMAReporter::PLUGIN_TYPE_MAX);
      break;
    default:
      NOTREACHED();
  }
}

// static.
PluginUMAReporter* PluginUMAReporter::GetInstance() {
  return Singleton<PluginUMAReporter>::get();
}

void PluginUMAReporter::ReportPluginMissing(const std::string& plugin_mime_type,
                                            const GURL& plugin_src) {
  report_sender_->SendPluginUMA(MISSING_PLUGIN,
                                GetPluginType(plugin_mime_type, plugin_src));
}

void PluginUMAReporter::ReportPluginDisabled(
    const std::string& plugin_mime_type,
    const GURL& plugin_src) {
  report_sender_->SendPluginUMA(DISABLED_PLUGIN,
                                GetPluginType(plugin_mime_type, plugin_src));
}

PluginUMAReporter::PluginUMAReporter() : report_sender_(new UMASenderImpl()) {}

PluginUMAReporter::~PluginUMAReporter() {}

// static.
bool PluginUMAReporter::CompareCStrings(const char* first, const char* second) {
  return strcmp(first, second) < 0;
}

bool PluginUMAReporter::CStringArrayContainsCString(const char** array,
                                                    size_t array_size,
                                                    const char* str) {
  return std::binary_search(array, array + array_size, str, CompareCStrings);
}

void PluginUMAReporter::ExtractFileExtension(const GURL& src,
                                             std::string* extension) {
  std::string extension_file_path(src.ExtractFileName());
  if (extension_file_path.empty())
    extension_file_path = src.host();

  size_t last_dot = extension_file_path.find_last_of('.');
  if (last_dot != std::string::npos) {
    *extension = extension_file_path.substr(last_dot);
  } else {
    extension->clear();
  }

  StringToLowerASCII(extension);
}

PluginUMAReporter::PluginType PluginUMAReporter::GetPluginType(
    const std::string& plugin_mime_type,
    const GURL& plugin_src) {
  // If we know plugin's mime type, we use it to determine plugin's type. Else,
  // we try to determine plugin type using plugin source's extension.
  if (!plugin_mime_type.empty())
    return MimeTypeToPluginType(StringToLowerASCII(plugin_mime_type));

  return SrcToPluginType(plugin_src);
}

PluginUMAReporter::PluginType PluginUMAReporter::SrcToPluginType(
    const GURL& src) {
  std::string file_extension;
  ExtractFileExtension(src, &file_extension);
  if (CStringArrayContainsCString(kWindowsMediaPlayerExtensions,
                                  arraysize(kWindowsMediaPlayerExtensions),
                                  file_extension.c_str())) {
    return WINDOWS_MEDIA_PLAYER;
  }

  if (CStringArrayContainsCString(kQuickTimeExtensions,
                                  arraysize(kQuickTimeExtensions),
                                  file_extension.c_str())) {
    return QUICKTIME;
  }

  if (CStringArrayContainsCString(kRealPlayerExtensions,
                                  arraysize(kRealPlayerExtensions),
                                  file_extension.c_str())) {
    return REALPLAYER;
  }

  if (CStringArrayContainsCString(kShockwaveFlashExtensions,
                                  arraysize(kShockwaveFlashExtensions),
                                  file_extension.c_str())) {
    return SHOCKWAVE_FLASH;
  }

  return UNSUPPORTED_EXTENSION;
}

PluginUMAReporter::PluginType PluginUMAReporter::MimeTypeToPluginType(
    const std::string& mime_type) {
  if (mime_type == kWindowsMediaPlayerType)
    return WINDOWS_MEDIA_PLAYER;

  size_t prefix_length = strlen(kSilverlightTypePrefix);
  if (strncmp(mime_type.c_str(), kSilverlightTypePrefix, prefix_length) == 0)
    return SILVERLIGHT;

  prefix_length = strlen(kRealPlayerTypePrefix);
  if (strncmp(mime_type.c_str(), kRealPlayerTypePrefix, prefix_length) == 0)
    return REALPLAYER;

  if (strstr(mime_type.c_str(), kJavaTypeSubstring))
    return JAVA;

  if (mime_type == kQuickTimeType)
    return QUICKTIME;

  if (mime_type == content::kBrowserPluginMimeType)
    return BROWSER_PLUGIN;

  if (mime_type == content::kFlashPluginSwfMimeType ||
      mime_type == content::kFlashPluginSplMimeType) {
    return SHOCKWAVE_FLASH;
  }

#if defined(ENABLE_PEPPER_CDMS)
  if (mime_type == kWidevineCdmPluginMimeType)
    return WIDEVINE_CDM;
#endif

  return UNSUPPORTED_MIMETYPE;
}
