// Copyright (c) 2013 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/browser/extensions/activity_log/activity_actions.h"

#include <string>

#include "base/command_line.h"
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/activity_log/activity_action_constants.h"
#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/dom_action_types.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "sql/statement.h"

namespace constants = activity_log_constants;

namespace {

std::string Serialize(const base::Value* value) {
  std::string value_as_text;
  if (!value) {
    value_as_text = "null";
  } else {
    JSONStringValueSerializer serializer(&value_as_text);
    serializer.SerializeAndOmitBinaryValues(*value);
  }
  return value_as_text;
}

}  // namespace

namespace extensions {

using api::activity_log_private::ExtensionActivity;

Action::Action(const std::string& extension_id,
               const base::Time& time,
               const ActionType action_type,
               const std::string& api_name)
    : extension_id_(extension_id),
      time_(time),
      action_type_(action_type),
      api_name_(api_name),
      page_incognito_(false),
      arg_incognito_(false),
      count_(0) {}

Action::~Action() {}

// TODO(mvrable): As an optimization, we might return this directly if the
// refcount is one.  However, there are likely to be other stray references in
// many cases that will prevent this optimization.
scoped_refptr<Action> Action::Clone() const {
  scoped_refptr<Action> clone(
      new Action(extension_id(), time(), action_type(), api_name()));
  if (args())
    clone->set_args(make_scoped_ptr(args()->DeepCopy()));
  clone->set_page_url(page_url());
  clone->set_page_title(page_title());
  clone->set_page_incognito(page_incognito());
  clone->set_arg_url(arg_url());
  clone->set_arg_incognito(arg_incognito());
  if (other())
    clone->set_other(make_scoped_ptr(other()->DeepCopy()));
  return clone;
}

void Action::set_args(scoped_ptr<ListValue> args) {
  args_.reset(args.release());
}

ListValue* Action::mutable_args() {
  if (!args_.get()) {
    args_.reset(new ListValue());
  }
  return args_.get();
}

void Action::set_page_url(const GURL& page_url) {
  page_url_ = page_url;
}

void Action::set_arg_url(const GURL& arg_url) {
  arg_url_ = arg_url;
}

void Action::set_other(scoped_ptr<DictionaryValue> other) {
  other_.reset(other.release());
}

DictionaryValue* Action::mutable_other() {
  if (!other_.get()) {
    other_.reset(new DictionaryValue());
  }
  return other_.get();
}

std::string Action::SerializePageUrl() const {
  return (page_incognito() ? constants::kIncognitoUrl : "") + page_url().spec();
}

void Action::ParsePageUrl(const std::string& url) {
  set_page_incognito(StartsWithASCII(url, constants::kIncognitoUrl, true));
  if (page_incognito())
    set_page_url(GURL(url.substr(strlen(constants::kIncognitoUrl))));
  else
    set_page_url(GURL(url));
}

std::string Action::SerializeArgUrl() const {
  return (arg_incognito() ? constants::kIncognitoUrl : "") + arg_url().spec();
}

void Action::ParseArgUrl(const std::string& url) {
  set_arg_incognito(StartsWithASCII(url, constants::kIncognitoUrl, true));
  if (arg_incognito())
    set_arg_url(GURL(url.substr(strlen(constants::kIncognitoUrl))));
  else
    set_arg_url(GURL(url));
}

scoped_ptr<ExtensionActivity> Action::ConvertToExtensionActivity() {
  scoped_ptr<ExtensionActivity> result(new ExtensionActivity);

  // We do this translation instead of using the same enum because the database
  // values need to be stable; this allows us to change the extension API
  // without affecting the database.
  switch (action_type()) {
    case ACTION_API_CALL:
      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_API_CALL;
      break;
    case ACTION_API_EVENT:
      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_API_EVENT;
      break;
    case ACTION_CONTENT_SCRIPT:
      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_CONTENT_SCRIPT;
      break;
    case ACTION_DOM_ACCESS:
      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_DOM_ACCESS;
      break;
    case ACTION_DOM_EVENT:
      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_DOM_EVENT;
      break;
    case ACTION_WEB_REQUEST:
      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_WEB_REQUEST;
      break;
    case UNUSED_ACTION_API_BLOCKED:
    case ACTION_ANY:
    default:
      // This shouldn't be reached, but some people might have old or otherwise
      // weird db entries. Treat it like an API call if that happens.
      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_API_CALL;
      break;
  }

  result->extension_id.reset(new std::string(extension_id()));
  result->time.reset(new double(time().ToJsTime()));
  result->count.reset(new double(count()));
  result->api_call.reset(new std::string(api_name()));
  result->args.reset(new std::string(Serialize(args())));
  if (page_url().is_valid()) {
    if (!page_title().empty())
      result->page_title.reset(new std::string(page_title()));
    result->page_url.reset(new std::string(SerializePageUrl()));
  }
  if (arg_url().is_valid())
    result->arg_url.reset(new std::string(SerializeArgUrl()));

  if (other()) {
    scoped_ptr<ExtensionActivity::Other> other_field(
        new ExtensionActivity::Other);
    bool prerender;
    if (other()->GetBooleanWithoutPathExpansion(constants::kActionPrerender,
                                                &prerender)) {
      other_field->prerender.reset(new bool(prerender));
    }
    const DictionaryValue* web_request;
    if (other()->GetDictionaryWithoutPathExpansion(constants::kActionWebRequest,
                                                   &web_request)) {
      other_field->web_request.reset(new std::string(
          ActivityLogPolicy::Util::Serialize(web_request)));
    }
    std::string extra;
    if (other()->GetStringWithoutPathExpansion(constants::kActionExtra, &extra))
      other_field->extra.reset(new std::string(extra));
    int dom_verb;
    if (other()->GetIntegerWithoutPathExpansion(constants::kActionDomVerb,
                                                &dom_verb)) {
      switch (static_cast<DomActionType::Type>(dom_verb)) {
        case DomActionType::GETTER:
          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_GETTER;
          break;
        case DomActionType::SETTER:
          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_SETTER;
          break;
        case DomActionType::METHOD:
          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_METHOD;
          break;
        case DomActionType::INSERTED:
          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_INSERTED;
          break;
        case DomActionType::XHR:
          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_XHR;
          break;
        case DomActionType::WEBREQUEST:
          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_WEBREQUEST;
          break;
        case DomActionType::MODIFIED:
          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_MODIFIED;
          break;
        default:
          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_NONE;
      }
    } else {
      other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_NONE;
    }
    result->other.reset(other_field.release());
  }

  return result.Pass();
}

std::string Action::PrintForDebug() const {
  std::string result = "ID=" + extension_id() + " CATEGORY=";
  switch (action_type_) {
    case ACTION_API_CALL:
      result += "api_call";
      break;
    case ACTION_API_EVENT:
      result += "api_event_callback";
      break;
    case ACTION_WEB_REQUEST:
      result += "webrequest";
      break;
    case ACTION_CONTENT_SCRIPT:
      result += "content_script";
      break;
    case UNUSED_ACTION_API_BLOCKED:
      // This is deprecated.
      result += "api_blocked";
      break;
    case ACTION_DOM_EVENT:
      result += "dom_event";
      break;
    case ACTION_DOM_ACCESS:
      result += "dom_access";
      break;
    default:
      result += base::StringPrintf("type%d", static_cast<int>(action_type_));
  }

  result += " API=" + api_name_;
  if (args_.get()) {
    result += " ARGS=" + Serialize(args_.get());
  }
  if (page_url_.is_valid()) {
    if (page_incognito_)
      result += " PAGE_URL=(incognito)" + page_url_.spec();
    else
      result += " PAGE_URL=" + page_url_.spec();
  }
  if (!page_title_.empty()) {
    StringValue title(page_title_);
    result += " PAGE_TITLE=" + Serialize(&title);
  }
  if (arg_url_.is_valid()) {
    if (arg_incognito_)
      result += " ARG_URL=(incognito)" + arg_url_.spec();
    else
      result += " ARG_URL=" + arg_url_.spec();
  }
  if (other_.get()) {
    result += " OTHER=" + Serialize(other_.get());
  }

  result += base::StringPrintf(" COUNT=%d", count_);
  return result;
}

bool ActionComparator::operator()(
    const scoped_refptr<Action>& lhs,
    const scoped_refptr<Action>& rhs) const {
  if (lhs->time() != rhs->time())
    return lhs->time() < rhs->time();
  else
    return ActionComparatorExcludingTime()(lhs, rhs);
}

bool ActionComparatorExcludingTime::operator()(
    const scoped_refptr<Action>& lhs,
    const scoped_refptr<Action>& rhs) const {
  if (lhs->extension_id() != rhs->extension_id())
    return lhs->extension_id() < rhs->extension_id();
  if (lhs->action_type() != rhs->action_type())
    return lhs->action_type() < rhs->action_type();
  if (lhs->api_name() != rhs->api_name())
    return lhs->api_name() < rhs->api_name();

  // args might be null; treat a null value as less than all non-null values,
  // including the empty string.
  if (!lhs->args() && rhs->args())
    return true;
  if (lhs->args() && !rhs->args())
    return false;
  if (lhs->args() && rhs->args()) {
    std::string lhs_args = ActivityLogPolicy::Util::Serialize(lhs->args());
    std::string rhs_args = ActivityLogPolicy::Util::Serialize(rhs->args());
    if (lhs_args != rhs_args)
      return lhs_args < rhs_args;
  }

  // Compare URLs as strings, and treat the incognito flag as a separate field.
  if (lhs->page_url().spec() != rhs->page_url().spec())
    return lhs->page_url().spec() < rhs->page_url().spec();
  if (lhs->page_incognito() != rhs->page_incognito())
    return lhs->page_incognito() < rhs->page_incognito();

  if (lhs->page_title() != rhs->page_title())
    return lhs->page_title() < rhs->page_title();

  if (lhs->arg_url().spec() != rhs->arg_url().spec())
    return lhs->arg_url().spec() < rhs->arg_url().spec();
  if (lhs->arg_incognito() != rhs->arg_incognito())
    return lhs->arg_incognito() < rhs->arg_incognito();

  // other is treated much like the args field.
  if (!lhs->other() && rhs->other())
    return true;
  if (lhs->other() && !rhs->other())
    return false;
  if (lhs->other() && rhs->other()) {
    std::string lhs_other = ActivityLogPolicy::Util::Serialize(lhs->other());
    std::string rhs_other = ActivityLogPolicy::Util::Serialize(rhs->other());
    if (lhs_other != rhs_other)
      return lhs_other < rhs_other;
  }

  // All fields compare as equal if this point is reached.
  return false;
}

}  // namespace extensions
