// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cstdio>
#include <map>

#include "base/command_line.h"
#include "base/threading/thread.h"
#include "base/time.h"
#include "cobalt/base/c_val.h"
#include "cobalt/base/wrap_main.h"
#include "cobalt/browser/application.h"
#include "cobalt/browser/switches.h"

namespace {

// How many seconds to wait after starting the application before taking the
// snapshot of CVal values.
const int kSecondsToWait = 20;

// The list of CVals we are interested in reporting.
//
// Note that if you add an item to this list, you should also add a column
// to the stats tracking table in the database. Please see the document titled
// "Adding a SnapshotAppStats column" on the Cobalt intranet home page for
// examples on how to add a new column.

// The naming convention for CVal columns in the database are the same as the
// name of the CVal except with the dots removed and the CVal name converted to
// camel case.  For example, "DOM.TokenLists" would become "dOMTokenLists".
//
// A document that explains how to modify the database in more detail can be
// found called "Dashboard TDD" on the Cobalt intranet home page.

const char* g_cvals_to_snapshot[] = {
    "Count.DOM.Nodes",
    "Count.DOM.TokenLists",
    "Count.XHR",
    "Memory.ArrayBuffer",
    "Memory.CPU.Exe",
    "Memory.CPU.Used",
    "Memory.GraphicsPS3.Fixed.Size",
    "Memory.JS",
    "Memory.MainWebModule.ImageCache.Size",
    "Memory.MainWebModule.RemoteTypefaceCache.Size",
    "Memory.Media.AudioDecoder",
    "Memory.Media.MediaSource.CPU.Fixed.Capacity",
    "Memory.Media.VideoDecoder",
    "Memory.XHR",
};

PRINTF_FORMAT(1, 2) void Output(const char* fmt, ...) {
  va_list ap;
  va_start(ap, fmt);

  std::vfprintf(stdout, fmt, ap);

  va_end(ap);

  std::fflush(stdout);
}

typedef std::map<std::string, std::string> CValsMap;

// Returns all CVals along with their values.
CValsMap GetAllCValValues() {
  base::CValManager* cvm = base::CValManager::GetInstance();
  std::set<std::string> cvals = cvm->GetOrderedCValNames();
  CValsMap cvals_with_values;

  for (std::set<std::string>::iterator iter = cvals.begin();
       iter != cvals.end(); ++iter) {
    base::optional<std::string> cval_value = cvm->GetValueAsString(*iter);
    if (cval_value) {
      cvals_with_values[*iter] = *cval_value;
    }
  }

  return cvals_with_values;
}

// Grab a snapshot of all current CVals and their values and then output them
// so that they can be analyzed by humans and inserted into a database where
// the values can be graphed.
void DoStatsSnapshot(cobalt::browser::Application* application) {
  Output("---Benchmark Results Start---\n");
  Output("{\n");
  Output("  \"LiveYouTubeAfter%dSecondsStatsSnapshot\": {\n", kSecondsToWait);

  CValsMap cval_values = GetAllCValValues();
  bool have_printed_results = false;
  for (size_t i = 0; i < arraysize(g_cvals_to_snapshot); ++i) {
    CValsMap::iterator found = cval_values.find(g_cvals_to_snapshot[i]);
    if (found != cval_values.end()) {
      if (have_printed_results) {
        Output(",\n");
      } else {
        have_printed_results = true;
      }
      Output("    \"%s\": %s", found->first.c_str(), found->second.c_str());
    }
  }

  Output("\n");

  Output("  }\n");
  Output("}\n");
  Output("---Benchmark Results End---\n");

  application->Quit();
}

}  // namespace

namespace {

cobalt::browser::Application* g_application = NULL;
base::Thread* g_snapshot_thread = NULL;

void StartApplication(int /*argc*/, char* /*argv*/ [], const char* /*link*/,
                      const base::Closure& quit_closure) {
  logging::SetMinLogLevel(100);

  // Use null storage for our savegame so that we don't persist state from
  // one run to another, which makes the measurements more deterministic (e.g.
  // we will not consistently register for experiments via cookies).
  CommandLine::ForCurrentProcess()->AppendSwitch(
      cobalt::browser::switches::kNullSavegame);
  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      cobalt::browser::switches::kDebugConsoleMode, "off");

  // Create the application object just like is done in the Cobalt main app.
  g_application = cobalt::browser::CreateApplication(quit_closure).release();

  // Create a thread to start a timer for kSecondsToWait seconds after which
  // we will take a snapshot of the CVals at that time and then quit the
  // application.
  g_snapshot_thread = new base::Thread("StatsSnapshot");
  g_snapshot_thread->Start();
  g_snapshot_thread->message_loop()->PostDelayedTask(
      FROM_HERE, base::Bind(&DoStatsSnapshot, g_application),
      base::TimeDelta::FromSeconds(kSecondsToWait));
}

void StopApplication() {
  g_snapshot_thread->Stop();
  delete g_application;
  g_application = NULL;
}

}  // namespace

COBALT_WRAP_BASE_MAIN(StartApplication, StopApplication);
