// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "usage_stats/usage_stats.h"

#include <algorithm>
#include <numeric>

#include "base/logging.h"
#include "config/stats_config_util.h"
#include "storage/registry.h"
#include "usage_stats/usage_stats.pb.h"

namespace mozc {
namespace usage_stats {

namespace {
const char kRegistryPrefix[] = "usage_stats.";

#include "usage_stats/usage_stats_list.h"

void AddDoubleValueStats(
    const Stats::DoubleValueStats &src,
    Stats::DoubleValueStats *dest) {
  dest->set_num(src.num() + dest->num());
  dest->set_total(src.total() + dest->total());
  dest->set_square_total(src.square_total() + dest->square_total());
}

void AddTouchEventStats(
    const Stats::TouchEventStats &src_stats,
    Stats::TouchEventStats *dest_stats) {
  dest_stats->set_source_id(src_stats.source_id());
  AddDoubleValueStats(src_stats.start_x_stats(),
                      dest_stats->mutable_start_x_stats());
  AddDoubleValueStats(src_stats.start_y_stats(),
                      dest_stats->mutable_start_y_stats());
  AddDoubleValueStats(src_stats.direction_x_stats(),
                      dest_stats->mutable_direction_x_stats());
  AddDoubleValueStats(src_stats.direction_y_stats(),
                      dest_stats->mutable_direction_y_stats());
  AddDoubleValueStats(src_stats.time_length_stats(),
                      dest_stats->mutable_time_length_stats());
}

bool LoadStats(const string &name, Stats *stats) {
  DCHECK(UsageStats::IsListed(name)) << name << " is not in the list";
  string stats_str;
  const string key = kRegistryPrefix + name;
  if (!mozc::storage::Registry::Lookup(key, &stats_str)) {
    VLOG(1) << "Usage stats " << name << " is not registered yet.";
    return false;
  }
  if (!stats->ParseFromString(stats_str)) {
    LOG(ERROR) << "Parse error";
    return false;
  }
  return true;
}

bool GetterInternal(const string &name, Stats::Type type, Stats *stats) {
  if (!LoadStats(name, stats)) {
    return false;
  }
  if (stats->type() != type) {
    LOG(ERROR) << "Type of " << name << " is not " << type
               << " but " << stats->type() << ".";
    return false;
  }
  return true;
}

bool SetterInternal(const string &name, const Stats &stats) {
  const string key = kRegistryPrefix + name;
  const string stats_str = stats.SerializeAsString();
  if (!storage::Registry::Insert(key, stats_str)) {
    LOG(ERROR) << "cannot save " << name << " to registry";
    return false;
  }
  return true;
}
}  // namespace

bool UsageStats::IsListed(const string &name) {
  for (size_t i = 0; i < arraysize(kStatsList); ++i) {
    if (name == kStatsList[i]) {
      return true;
    }
  }
  return false;
}

void UsageStats::ClearStats() {
  string stats_str;
  Stats stats;
  for (size_t i = 0; i < arraysize(kStatsList); ++i) {
    const string key = string(kRegistryPrefix) + kStatsList[i];
    if (storage::Registry::Lookup(key, &stats_str)) {
      if (!stats.ParseFromString(stats_str)) {
        storage::Registry::Erase(key);
      }
      if (stats.type() == Stats::INTEGER ||
          stats.type() == Stats::BOOLEAN) {
        // We do not clear integer/boolean stats.
        // These stats do not accumulate.
        // We want send these stats at the next time
        // even if they are not updated.
        continue;
      }
      storage::Registry::Erase(key);
    }
  }
}

void UsageStats::ClearAllStatsForTest() {
  for (size_t i = 0; i < arraysize(kStatsList); ++i) {
    const string key = string(kRegistryPrefix) + kStatsList[i];
    storage::Registry::Erase(key);
  }
}

void UsageStats::IncrementCountBy(const string &name, uint32 val) {
  DCHECK(IsListed(name)) << name << " is not in the list";
  if (!config::StatsConfigUtil::IsEnabled()) {
    return;
  }

  Stats stats;
  if (GetterInternal(name, Stats::COUNT, &stats)) {
    stats.set_count(stats.count() + val);
  } else {
    stats.set_name(name);
    stats.set_type(Stats::COUNT);
    stats.set_count(val);
  }

  SetterInternal(name, stats);
}

void UsageStats::UpdateTiming(const string &name, uint32 val) {
  DCHECK(IsListed(name)) << name << " is not in the list";
  if (!config::StatsConfigUtil::IsEnabled()) {
    return;
  }

  Stats stats;
  if (GetterInternal(name, Stats::TIMING, &stats)) {
    stats.set_num_timings(stats.num_timings() + 1);
    stats.set_total_time(stats.total_time() + val);
    stats.set_avg_time(stats.total_time() / stats.num_timings());
    stats.set_min_time(min(stats.min_time(), val));
    stats.set_max_time(max(stats.max_time(), val));
  } else {
    stats.set_name(name);
    stats.set_type(Stats::TIMING);
    stats.set_num_timings(1);
    stats.set_total_time(val);
    stats.set_avg_time(val);
    stats.set_min_time(val);
    stats.set_max_time(val);
  }

  SetterInternal(name, stats);
}

void UsageStats::SetInteger(const string &name, int val) {
  DCHECK(IsListed(name)) << name << " is not in the list";
  if (!config::StatsConfigUtil::IsEnabled()) {
    return;
  }

  Stats stats;
  stats.set_name(name);
  stats.set_type(Stats::INTEGER);
  stats.set_int_value(val);

  SetterInternal(name, stats);
}

void UsageStats::SetBoolean(const string &name, bool val) {
  DCHECK(IsListed(name)) << name << " is not in the list";
  if (!config::StatsConfigUtil::IsEnabled()) {
    return;
  }

  Stats stats;
  stats.set_name(name);
  stats.set_type(Stats::BOOLEAN);
  stats.set_boolean_value(val);

  SetterInternal(name, stats);
}

bool UsageStats::GetCountForTest(const string &name, uint32 *value) {
  CHECK(value != NULL);
  Stats stats;
  if (!GetterInternal(name, Stats::COUNT, &stats)) {
    return false;
  }
  if (!stats.has_count()) {
    LOG(WARNING) << name << " has no counts.";
    return false;
  }

  *value = stats.count();
  return true;
}

bool UsageStats::GetIntegerForTest(const string &name, int32 *value) {
  CHECK(value != NULL);
  Stats stats;
  if (!GetterInternal(name, Stats::INTEGER, &stats)) {
    return false;
  }
  if (!stats.has_int_value()) {
    LOG(WARNING) << name << " has no integer values.";
    return false;
  }

  *value = stats.int_value();
  return true;
}

bool UsageStats::GetBooleanForTest(const string &name, bool *value) {
  CHECK(value != NULL);
  Stats stats;
  if (!GetterInternal(name, Stats::BOOLEAN, &stats)) {
    return false;
  }
  if (!stats.has_boolean_value()) {
    LOG(WARNING) << name << " has no boolean values.";
    return false;
  }

  *value = stats.boolean_value();
  return true;
}

bool UsageStats::GetTimingForTest(const string &name,
                                  uint64 *total_time,
                                  uint32 *num_timings,
                                  uint32 *avg_time,
                                  uint32 *min_time,
                                  uint32 *max_time) {
  Stats stats;
  if (!GetterInternal(name, Stats::TIMING, &stats)) {
    return false;
  }

  if ((total_time != NULL && !stats.has_total_time()) ||
      (num_timings != NULL && !stats.has_num_timings()) ||
      (avg_time != NULL && !stats.has_avg_time()) ||
      (min_time != NULL && !stats.has_min_time()) ||
      (max_time != NULL && !stats.has_max_time())) {
    LOG(WARNING) << "cannot import stats of " << name << ".";
    return false;
  }

  if (total_time != NULL) {
    *total_time = stats.total_time();
  }
  if (num_timings != NULL) {
    *num_timings = stats.num_timings();
  }
  if (avg_time != NULL) {
    *avg_time = stats.avg_time();
  }
  if (min_time != NULL) {
    *min_time = stats.min_time();
  }
  if (max_time != NULL) {
    *max_time = stats.max_time();
  }

  return true;
}

bool UsageStats::GetVirtualKeyboardForTest(const string &name, Stats *stats) {
  if (!GetterInternal(name, Stats::VIRTUAL_KEYBOARD, stats)) {
    return false;
  }

  if (stats->virtual_keyboard_stats_size() == 0) {
    LOG(WARNING) << name << " has no virtual keyboard values.";
    stats->Clear();
    return false;
  }

  return true;
}

bool UsageStats::GetStatsForTest(const string &name, Stats *stats) {
  return LoadStats(name, stats);
}

void UsageStats::StoreTouchEventStats(
    const string &name, const map<string, TouchEventStatsMap> &touch_stats) {
  DCHECK(IsListed(name)) << name << " is not in the list";
  if (touch_stats.empty()) {
    return;
  }

  Stats stats;
  map<string, TouchEventStatsMap> tmp_stats(touch_stats);
  if (GetterInternal(name, Stats::VIRTUAL_KEYBOARD, &stats)) {
    for (size_t i = 0; i < stats.virtual_keyboard_stats_size(); ++i) {
      const Stats::VirtualKeyboardStats &virtual_keyboard_stats =
          stats.virtual_keyboard_stats(i);
      const string &keyboard_name = virtual_keyboard_stats.keyboard_name();
      TouchEventStatsMap &stats_map = tmp_stats[keyboard_name];

      for (size_t j = 0; j < virtual_keyboard_stats.touch_event_stats_size();
          ++j) {
        const Stats::TouchEventStats &src_stats =
            virtual_keyboard_stats.touch_event_stats(j);
        Stats::TouchEventStats &dest_stats = stats_map[src_stats.source_id()];
        AddTouchEventStats(src_stats, &dest_stats);
      }
    }
  } else {
    stats.set_name(name);
    stats.set_type(Stats::VIRTUAL_KEYBOARD);
  }

  stats.clear_virtual_keyboard_stats();
  for (map<string, TouchEventStatsMap>::const_iterator iter =
           tmp_stats.begin();
       iter != tmp_stats.end(); ++iter) {
    Stats::VirtualKeyboardStats *virtual_keyboard_stats =
        stats.add_virtual_keyboard_stats();
    virtual_keyboard_stats->set_keyboard_name(iter->first);
    for (TouchEventStatsMap::const_iterator it = iter->second.begin();
        it != iter->second.end(); ++it) {
      Stats::TouchEventStats *touch_event_stats =
          virtual_keyboard_stats->add_touch_event_stats();
      touch_event_stats->CopyFrom(it->second);
    }
  }

  SetterInternal(name, stats);
}

bool UsageStats::Sync() {
  if (!storage::Registry::Sync()) {
    LOG(ERROR) << "sync failed";
    return false;
  }
  return true;
}

}  // namespace usage_stats
}  // namespace mozc
