// 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 "cobalt/browser/application.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/time.h"
#include "build/build_config.h"
#include "cobalt/base/accessibility_settings_changed_event.h"
#include "cobalt/base/application_event.h"
#include "cobalt/base/cobalt_paths.h"
#include "cobalt/base/deep_link_event.h"
#include "cobalt/base/get_application_key.h"
#include "cobalt/base/init_cobalt.h"
#include "cobalt/base/language.h"
#include "cobalt/base/localized_strings.h"
#include "cobalt/base/startup_timer.h"
#include "cobalt/base/user_log.h"
#include "cobalt/browser/memory_settings/auto_mem_settings.h"
#include "cobalt/browser/memory_tracker/tool.h"
#include "cobalt/browser/switches.h"
#include "cobalt/loader/image/image_decoder.h"
#include "cobalt/math/size.h"
#include "cobalt/network/network_event.h"
#include "cobalt/script/javascript_engine.h"
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
#include "cobalt/storage/savegame_fake.h"
#endif
#include "cobalt/system_window/input_event.h"
#include "cobalt/trace_event/scoped_trace_to_file.h"
#include "googleurl/src/gurl.h"
#include "starboard/configuration.h"

namespace cobalt {
namespace browser {

namespace {
const int kStatUpdatePeriodMs = 1000;

const char kDefaultURL[] = "https://www.youtube.com/tv";

bool IsStringNone(const std::string& str) {
  return !base::strcasecmp(str.c_str(), "none");
}

#if defined(ENABLE_REMOTE_DEBUGGING)
int GetRemoteDebuggingPort() {
#if defined(SB_OVERRIDE_DEFAULT_REMOTE_DEBUGGING_PORT)
  const int kDefaultRemoteDebuggingPort =
      SB_OVERRIDE_DEFAULT_REMOTE_DEBUGGING_PORT;
#else
  const int kDefaultRemoteDebuggingPort = 9222;
#endif  // defined(SB_OVERRIDE_DEFAULT_REMOTE_DEBUGGING_PORT)
  int remote_debugging_port = kDefaultRemoteDebuggingPort;
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kRemoteDebuggingPort)) {
    const std::string switchValue =
        command_line->GetSwitchValueASCII(switches::kRemoteDebuggingPort);
    if (!base::StringToInt(switchValue, &remote_debugging_port)) {
      DLOG(ERROR) << "Invalid port specified for remote debug server: "
                  << switchValue
                  << ". Using default port: " << kDefaultRemoteDebuggingPort;
      remote_debugging_port = kDefaultRemoteDebuggingPort;
    }
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
  return remote_debugging_port;
}
#endif  // ENABLE_REMOTE_DEBUGGING

#if defined(ENABLE_WEBDRIVER)
int GetWebDriverPort() {
  // The default port on which the webdriver server should listen for incoming
  // connections.
#if defined(SB_OVERRIDE_DEFAULT_WEBDRIVER_PORT)
  const int kDefaultWebDriverPort = SB_OVERRIDE_DEFAULT_WEBDRIVER_PORT;
#else
  const int kDefaultWebDriverPort = 4444;
#endif  // defined(SB_OVERRIDE_DEFAULT_WEBDRIVER_PORT)
  int webdriver_port = kDefaultWebDriverPort;
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kWebDriverPort)) {
    if (!base::StringToInt(
            command_line->GetSwitchValueASCII(switches::kWebDriverPort),
            &webdriver_port)) {
      DLOG(ERROR) << "Invalid port specified for WebDriver server: "
                  << command_line->GetSwitchValueASCII(switches::kWebDriverPort)
                  << ". Using default port: " << kDefaultWebDriverPort;
      webdriver_port = kDefaultWebDriverPort;
    }
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
  return webdriver_port;
}

std::string GetWebDriverListenIp() {
  // The default IP on which the webdriver server should listen for incoming
  // connections.
  std::string webdriver_listen_ip =
      webdriver::WebDriverModule::kDefaultListenIp;
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kWebDriverListenIp)) {
    webdriver_listen_ip =
        command_line->GetSwitchValueASCII(switches::kWebDriverListenIp);
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
  return webdriver_listen_ip;
}
#endif  // ENABLE_WEBDRIVER

GURL GetInitialURL() {
  // Allow the user to override the default URL via a command line parameter.
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kInitialURL)) {
    GURL url = GURL(command_line->GetSwitchValueASCII(switches::kInitialURL));
    if (url.is_valid()) {
      return url;
    } else {
      DLOG(ERROR) << "URL from parameter " << command_line
                  << " is not valid, using default URL.";
    }
  }

  return GURL(kDefaultURL);
}

base::optional<GURL> GetFallbackSplashScreenURL() {
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  std::string fallback_splash_screen_string;
  if (command_line->HasSwitch(switches::kFallbackSplashScreenURL)) {
    fallback_splash_screen_string =
        command_line->GetSwitchValueASCII(switches::kFallbackSplashScreenURL);
  } else {
    fallback_splash_screen_string = COBALT_FALLBACK_SPLASH_SCREEN_URL;
  }
  if (IsStringNone(fallback_splash_screen_string)) {
    return base::optional<GURL>();
  }
  base::optional<GURL> fallback_splash_screen_url =
      GURL(fallback_splash_screen_string);
  if (!fallback_splash_screen_url->is_valid() ||
      !(fallback_splash_screen_url->SchemeIsFile() ||
        fallback_splash_screen_url->SchemeIs("h5vcc-embedded"))) {
    LOG(FATAL) << "Ignoring invalid fallback splash screen: "
               << fallback_splash_screen_string;
  }
  return fallback_splash_screen_url;
}

base::TimeDelta GetTimedTraceDuration() {
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  int duration_in_seconds = 0;
  if (command_line->HasSwitch(switches::kTimedTrace) &&
      base::StringToInt(
          command_line->GetSwitchValueASCII(switches::kTimedTrace),
          &duration_in_seconds)) {
    return base::TimeDelta::FromSeconds(duration_in_seconds);
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

  return base::TimeDelta();
}

FilePath GetExtraWebFileDir() {
  // Default is empty, command line can override.
  FilePath result;

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kExtraWebFileDir)) {
    result =
        FilePath(command_line->GetSwitchValueASCII(switches::kExtraWebFileDir));
    if (!result.IsAbsolute()) {
      // Non-absolute paths are relative to the executable directory.
      FilePath content_path;
      PathService::Get(base::DIR_EXE, &content_path);
      result = content_path.DirName().DirName().Append(result);
    }
    DLOG(INFO) << "Extra web file dir: " << result.value();
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

  return result;
}

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
void EnableUsingStubImageDecoderIfRequired() {
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kStubImageDecoder)) {
    loader::image::ImageDecoder::UseStubImageDecoder();
  }
}
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
base::optional<math::Size> GetVideoOutputResolutionOverride(
    CommandLine* command_line) {
  DCHECK(command_line);
  if (command_line->HasSwitch(switches::kVideoContainerSizeOverride)) {
    std::string size_override = command_line->GetSwitchValueASCII(
        browser::switches::kVideoContainerSizeOverride);
    DLOG(INFO) << "Set video container size override from command line to "
               << size_override;
    // Override string should be something like "1920x1080".
    int32 width, height;
    std::vector<std::string> tokens;
    base::SplitString(size_override, 'x', &tokens);
    if (tokens.size() == 2 && base::StringToInt32(tokens[0], &width) &&
        base::StringToInt32(tokens[1], &height)) {
      return math::Size(width, height);
    }

    DLOG(WARNING) << "Invalid size specified for video container: "
                  << size_override;
  }

  return base::nullopt;
}
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

// Represents a parsed int.
struct ParsedIntValue {
 public:
  ParsedIntValue() : value_(0), error_(false) {}
  ParsedIntValue(const ParsedIntValue& other)
      : value_(other.value_), error_(other.error_) {}
  int value_;
  bool error_;  // true if there was a parse error.
};

// Parses a string like "1234x5678" to vector of parsed int values.
std::vector<ParsedIntValue> ParseDimensions(const std::string& value_str) {
  std::vector<ParsedIntValue> output;

  std::vector<std::string> lengths;
  base::SplitString(value_str, 'x', &lengths);

  for (size_t i = 0; i < lengths.size(); ++i) {
    ParsedIntValue parsed_value;
    parsed_value.error_ = !base::StringToInt(lengths[i], &parsed_value.value_);
    output.push_back(parsed_value);
  }
  return output;
}

base::optional<math::Size> GetRequestedViewportSize(CommandLine* command_line) {
  DCHECK(command_line);
  if (!command_line->HasSwitch(browser::switches::kViewport)) {
    return base::nullopt;
  }

  const std::string switchValue =
      command_line->GetSwitchValueASCII(browser::switches::kViewport);
  std::vector<ParsedIntValue> parsed_ints = ParseDimensions(switchValue);
  if (parsed_ints.size() < 1) {
    return base::nullopt;
  }

  const ParsedIntValue parsed_width = parsed_ints[0];
  if (parsed_width.error_) {
    DLOG(ERROR) << "Invalid value specified for viewport width: " << switchValue
                << ". Using default viewport size.";
    return base::nullopt;
  }

  const ParsedIntValue* parsed_height_ptr = NULL;
  if (parsed_ints.size() >= 2) {
    parsed_height_ptr = &parsed_ints[1];
  }

  if (!parsed_height_ptr) {
    // Allow shorthand specification of the viewport by only giving the
    // width. This calculates the height at 4:3 aspect ratio for smaller
    // viewport widths, and 16:9 for viewports 1280 pixels wide or larger.
    if (parsed_width.value_ >= 1280) {
      return math::Size(parsed_width.value_, 9 * parsed_width.value_ / 16);
    }

    return math::Size(parsed_width.value_, 3 * parsed_width.value_ / 4);
  }

  if (parsed_height_ptr->error_) {
    DLOG(ERROR) << "Invalid value specified for viewport height: "
                << switchValue << ". Using default viewport size.";
    return base::nullopt;
  }

  return math::Size(parsed_width.value_, parsed_height_ptr->value_);
}

std::string GetMinLogLevelString() {
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kMinLogLevel)) {
    return command_line->GetSwitchValueASCII(switches::kMinLogLevel);
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
  return "info";
}

int StringToLogLevel(const std::string& log_level) {
  if (log_level == "info") {
    return logging::LOG_INFO;
  } else if (log_level == "warning") {
    return logging::LOG_WARNING;
  } else if (log_level == "error") {
    return logging::LOG_ERROR;
  } else if (log_level == "fatal") {
    return logging::LOG_FATAL;
  } else {
    NOTREACHED() << "Unrecognized logging level: " << log_level;
    return logging::LOG_INFO;
  }
}

void SetIntegerIfSwitchIsSet(const char* switch_name, int* output) {
  if (CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) {
    int32 out;
    if (base::StringToInt32(
            CommandLine::ForCurrentProcess()->GetSwitchValueNative(switch_name),
            &out)) {
      LOG(INFO) << "Command line switch '" << switch_name << "': Modifying "
                << *output << " -> " << out;
      *output = out;
    } else {
      LOG(ERROR) << "Invalid value for command line setting: " << switch_name;
    }
  }
}

void ApplyCommandLineSettingsToRendererOptions(
    renderer::RendererModule::Options* options) {
  SetIntegerIfSwitchIsSet(browser::switches::kSurfaceCacheSizeInBytes,
                          &options->surface_cache_size_in_bytes);
  SetIntegerIfSwitchIsSet(browser::switches::kScratchSurfaceCacheSizeInBytes,
                          &options->scratch_surface_cache_size_in_bytes);
}

// Restrict navigation to a couple of whitelisted URLs by default.
const char kYouTubeTvLocationPolicy[] =
    "h5vcc-location-src "
    "https://s.ytimg.com/yts/cobalt/ "
    "https://www.youtube.com/tv "
    "https://www.youtube.com/tv/ "
    "https://web-green-qa.youtube.com/tv "
    "https://web-green-qa.youtube.com/tv/ "
    "https://web-release-qa.youtube.com/tv "
    "https://web-release-qa.youtube.com/tv/ "
#if defined(ENABLE_ABOUT_SCHEME)
    "about: "
#endif
    "h5vcc:";

#if !defined(COBALT_FORCE_CSP)
dom::CspEnforcementType StringToCspMode(const std::string& mode) {
  if (mode == "disable") {
    return dom::kCspEnforcementDisable;
  } else if (mode == "enable") {
    return dom::kCspEnforcementEnable;
  } else {
    DLOG(INFO) << "Invalid CSP mode: " << mode << ": use [disable|enable]";
    return dom::kCspEnforcementEnable;
  }
}
#endif  // !defined(COBALT_FORCE_CSP)

struct NonTrivialStaticFields {
  NonTrivialStaticFields() : system_language(base::GetSystemLanguage()) {}

  const std::string system_language;
  std::string user_agent;

 private:
  DISALLOW_COPY_AND_ASSIGN(NonTrivialStaticFields);
};

// |non_trivial_static_fields| will be lazily created on the first time it's
// accessed.
base::LazyInstance<NonTrivialStaticFields> non_trivial_static_fields =
    LAZY_INSTANCE_INITIALIZER;
}  // namespace

// Static user logs
ssize_t Application::available_memory_ = 0;
int64 Application::lifetime_in_ms_ = 0;

Application::AppStatus Application::app_status_ =
    Application::kUninitializedAppStatus;
int Application::app_pause_count_ = 0;
int Application::app_unpause_count_ = 0;
int Application::app_suspend_count_ = 0;
int Application::app_resume_count_ = 0;

Application::NetworkStatus Application::network_status_ =
    Application::kDisconnectedNetworkStatus;
int Application::network_connect_count_ = 0;
int Application::network_disconnect_count_ = 0;

Application::Application(const base::Closure& quit_closure, bool should_preload)
    : message_loop_(MessageLoop::current()),
      quit_closure_(quit_closure),
      stats_update_timer_(true, true) {
  // Check to see if a timed_trace has been set, indicating that we should
  // begin a timed trace upon startup.
  base::TimeDelta trace_duration = GetTimedTraceDuration();
  if (trace_duration != base::TimeDelta()) {
    trace_event::TraceToFileForDuration(
        FilePath(FILE_PATH_LITERAL("timed_trace.json")), trace_duration);
  }

  TRACE_EVENT0("cobalt::browser", "Application::Application()");

  DCHECK(MessageLoop::current());
  DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type());

  network_event_thread_checker_.DetachFromThread();
  application_event_thread_checker_.DetachFromThread();

  RegisterUserLogs();

  // Set the minimum logging level, if specified on the command line.
  logging::SetMinLogLevel(StringToLogLevel(GetMinLogLevelString()));

  stats_update_timer_.Start(
      FROM_HERE, base::TimeDelta::FromMilliseconds(kStatUpdatePeriodMs),
      base::Bind(&Application::UpdatePeriodicStats, base::Unretained(this)));

  // Get the initial URL.
  GURL initial_url = GetInitialURL();
  DLOG(INFO) << "Initial URL: " << initial_url;

  // Get the fallback splash screen URL.
  base::optional<GURL> fallback_splash_screen_url =
      GetFallbackSplashScreenURL();
  DLOG(INFO) << "Fallback splash screen URL: "
             << (fallback_splash_screen_url ? fallback_splash_screen_url->spec()
                                            : "none");

  // Get the system language and initialize our localized strings.
  std::string language = base::GetSystemLanguage();
  base::LocalizedStrings::GetInstance()->Initialize(language);

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  base::optional<math::Size> requested_viewport_size =
      GetRequestedViewportSize(command_line);

  WebModule::Options web_options;
  // Create the main components of our browser.
  BrowserModule::Options options(web_options);
  options.web_module_options.name = "MainWebModule";
  options.language = language;
  options.initial_deep_link = GetInitialDeepLink();
  options.network_module_options.preferred_language = language;
  options.command_line_auto_mem_settings =
      memory_settings::GetSettings(*command_line);
  options.build_auto_mem_settings = memory_settings::GetDefaultBuildSettings();
  options.fallback_splash_screen_url = fallback_splash_screen_url;

  if (command_line->HasSwitch(browser::switches::kFPSPrint)) {
    options.renderer_module_options.enable_fps_stdout = true;
  }
  if (command_line->HasSwitch(browser::switches::kFPSOverlay)) {
    options.renderer_module_options.enable_fps_overlay = true;
  }

  ApplyCommandLineSettingsToRendererOptions(&options.renderer_module_options);

  if (command_line->HasSwitch(browser::switches::kDisableJavaScriptJit)) {
    options.web_module_options.javascript_options.disable_jit = true;
  }

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  if (command_line->HasSwitch(browser::switches::kNullSavegame)) {
    options.storage_manager_options.savegame_options.factory =
        &storage::SavegameFake::Create;
  }
#endif

  base::optional<std::string> initial_key =
      base::GetApplicationKey(initial_url);
  options.storage_manager_options.savegame_options.id = initial_key;

  base::optional<std::string> default_key =
      base::GetApplicationKey(GURL(kDefaultURL));
  if (initial_key == default_key) {
    options.storage_manager_options.savegame_options.fallback_to_default_id =
        true;
  }

  // User can specify an extra search path entry for files loaded via file://.
  options.web_module_options.extra_web_file_dir = GetExtraWebFileDir();
  options.web_module_options.location_policy = kYouTubeTvLocationPolicy;
  // Set callback to be notified when a navigation occurs that destroys the
  // underlying WebModule.
  options.web_module_recreated_callback =
      base::Bind(&Application::WebModuleRecreated, base::Unretained(this));

  // The main web module's stat tracker tracks event stats.
  options.web_module_options.track_event_stats = true;

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  if (command_line->HasSwitch(browser::switches::kProxy)) {
    options.network_module_options.custom_proxy =
        command_line->GetSwitchValueASCII(browser::switches::kProxy);
  }

#if !defined(COBALT_FORCE_CSP)
  if (command_line->HasSwitch(browser::switches::kCspMode)) {
    options.web_module_options.csp_enforcement_mode = StringToCspMode(
        command_line->GetSwitchValueASCII(browser::switches::kCspMode));
  }
  if (options.web_module_options.csp_enforcement_mode !=
      dom::kCspEnforcementEnable) {
    options.web_module_options.location_policy = "h5vcc-location-src *";
  }
#endif  // !defined(COBALT_FORCE_CSP)

#if defined(ENABLE_IGNORE_CERTIFICATE_ERRORS)
  if (command_line->HasSwitch(browser::switches::kIgnoreCertificateErrors)) {
    options.network_module_options.ignore_certificate_errors = true;
  }
#endif  // defined(ENABLE_IGNORE_CERTIFICATE_ERRORS)

#if !defined(COBALT_FORCE_HTTPS)
  if (command_line->HasSwitch(switches::kAllowHttp)) {
    DLOG(INFO) << "Allowing insecure HTTP connections";
    options.network_module_options.require_https = false;
  }
#endif  // !defined(COBALT_FORCE_HTTPS)

  if (command_line->HasSwitch(switches::kVideoPlaybackRateMultiplier)) {
    double playback_rate = 1.0;
    base::StringToDouble(command_line->GetSwitchValueASCII(
                             switches::kVideoPlaybackRateMultiplier),
                         &playback_rate);
    options.web_module_options.video_playback_rate_multiplier =
        static_cast<float>(playback_rate);
    DLOG(INFO) << "Set video playback rate multiplier to "
               << options.web_module_options.video_playback_rate_multiplier;
  }

  EnableUsingStubImageDecoderIfRequired();

  if (command_line->HasSwitch(browser::switches::kDisableWebmVp9)) {
    DLOG(INFO) << "Webm/Vp9 disabled";
    options.media_module_options.disable_webm_vp9 = true;
  }
  if (command_line->HasSwitch(switches::kAudioDecoderStub)) {
    DLOG(INFO) << "Use ShellRawAudioDecoderStub";
    options.media_module_options.use_audio_decoder_stub = true;
  }
  if (command_line->HasSwitch(switches::kNullAudioStreamer)) {
    DLOG(INFO) << "Use null audio";
    options.media_module_options.use_null_audio_streamer = true;
  }
  if (command_line->HasSwitch(switches::kVideoDecoderStub)) {
    DLOG(INFO) << "Use ShellRawVideoDecoderStub";
    options.media_module_options.use_video_decoder_stub = true;
  }
  options.media_module_options.output_resolution_override =
      GetVideoOutputResolutionOverride(command_line);
  if (command_line->HasSwitch(switches::kMemoryTracker)) {
    std::string command_arg =
        command_line->GetSwitchValueASCII(switches::kMemoryTracker);
    memory_tracker_tool_ =
        memory_tracker::CreateMemoryTrackerTool(command_arg);
  }

  if (command_line->HasSwitch(switches::kDisableImageAnimations)) {
    options.web_module_options.enable_image_animations = false;
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

  if (command_line->HasSwitch(browser::switches::kDisableNavigationWhitelist)) {
    LOG(ERROR) << "\n"
               << "  *** Disabling the default navigation whitelist! ***\n"
               << "  *** Do not run in this mode in production!      ***";
    options.web_module_options.location_policy = "h5vcc-location-src *";
  }

  options.requested_viewport_size = requested_viewport_size;
  account_manager_.reset(new account::AccountManager());
  browser_module_.reset(
      new BrowserModule(initial_url,
                        (should_preload ? base::kApplicationStatePreloading
                                        : base::kApplicationStateStarted),
                        &event_dispatcher_, account_manager_.get(), options));
  UpdateAndMaybeRegisterUserAgent();

  app_status_ = (should_preload ? kPreloadingAppStatus : kRunningAppStatus);

  // Register event callbacks.
  network_event_callback_ =
      base::Bind(&Application::OnNetworkEvent, base::Unretained(this));
  event_dispatcher_.AddEventCallback(network::NetworkEvent::TypeId(),
                                     network_event_callback_);
  deep_link_event_callback_ =
      base::Bind(&Application::OnDeepLinkEvent, base::Unretained(this));
  event_dispatcher_.AddEventCallback(base::DeepLinkEvent::TypeId(),
                                     deep_link_event_callback_);

#if defined(ENABLE_WEBDRIVER)
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  bool create_webdriver_module =
      !command_line->HasSwitch(switches::kDisableWebDriver);
#else
  bool create_webdriver_module = true;
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
  if (create_webdriver_module) {
    web_driver_module_.reset(new webdriver::WebDriverModule(
        GetWebDriverPort(), GetWebDriverListenIp(),
        base::Bind(&BrowserModule::CreateSessionDriver,
                   base::Unretained(browser_module_.get())),
        base::Bind(&BrowserModule::RequestScreenshotToBuffer,
                   base::Unretained(browser_module_.get())),
        base::Bind(&BrowserModule::SetProxy,
                   base::Unretained(browser_module_.get())),
        base::Bind(&Application::Quit, base::Unretained(this))));
  }
#endif  // ENABLE_WEBDRIVER

#if defined(ENABLE_REMOTE_DEBUGGING)
  int remote_debugging_port = GetRemoteDebuggingPort();
  debug_web_server_.reset(new debug::DebugWebServer(
      remote_debugging_port,
      base::Bind(&BrowserModule::GetDebugServer,
                 base::Unretained(browser_module_.get()))));
#endif  // ENABLE_REMOTE_DEBUGGING

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  int duration_in_seconds = 0;
  if (command_line->HasSwitch(switches::kShutdownAfter) &&
      base::StringToInt(
          command_line->GetSwitchValueASCII(switches::kShutdownAfter),
          &duration_in_seconds)) {
    // If the "shutdown_after" command line option is specified, setup a delayed
    // message to quit the application after the specified number of seconds
    // have passed.
    message_loop_->PostDelayedTask(
        FROM_HERE, quit_closure_,
        base::TimeDelta::FromSeconds(duration_in_seconds));
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
}

Application::~Application() {
  // explicitly reset here because the destruction of the object is complex
  // and involves a thread join. If this were to hang the app then having
  // the destruction at this point gives a real file-line number and a place
  // for the debugger to land.
  memory_tracker_tool_.reset(NULL);

  // Unregister event callbacks.
  event_dispatcher_.RemoveEventCallback(network::NetworkEvent::TypeId(),
                                        network_event_callback_);
  event_dispatcher_.RemoveEventCallback(
      base::DeepLinkEvent::TypeId(), deep_link_event_callback_);

  app_status_ = kShutDownAppStatus;
}

void Application::Start() {
  if (MessageLoop::current() != message_loop_) {
    message_loop_->PostTask(
        FROM_HERE, base::Bind(&Application::Start, base::Unretained(this)));
    return;
  }

  if (app_status_ != kPreloadingAppStatus) {
    NOTREACHED() << __FUNCTION__ << ": Redundant call.";
    return;
  }

  OnApplicationEvent(kSbEventTypeStart);
}

void Application::Quit() {
  if (MessageLoop::current() != message_loop_) {
    message_loop_->PostTask(
        FROM_HERE, base::Bind(&Application::Quit, base::Unretained(this)));
    return;
  }

  DCHECK(!quit_closure_.is_null());
  if (!quit_closure_.is_null()) {
    quit_closure_.Run();
  }

  app_status_ = kQuitAppStatus;
}

void Application::HandleStarboardEvent(const SbEvent* starboard_event) {
  DCHECK(starboard_event);

  // Forward input events to |SystemWindow|.
  if (starboard_event->type == kSbEventTypeInput) {
    system_window::HandleInputEvent(starboard_event);
    return;
  }

  // Create a Cobalt event from the Starboard event, if recognized.
  switch (starboard_event->type) {
    case kSbEventTypePause:
    case kSbEventTypeUnpause:
    case kSbEventTypeSuspend:
    case kSbEventTypeResume:
#if SB_API_VERSION >= SB_LOW_MEMORY_EVENT_API_VERSION
    case kSbEventTypeLowMemory:
#endif  // SB_API_VERSION >= SB_LOW_MEMORY_EVENT_API_VERSION
      OnApplicationEvent(starboard_event->type);
      break;
    case kSbEventTypeNetworkConnect:
      DispatchEventInternal(
          new network::NetworkEvent(network::NetworkEvent::kConnection));
      break;
    case kSbEventTypeNetworkDisconnect:
      DispatchEventInternal(
          new network::NetworkEvent(network::NetworkEvent::kDisconnection));
      break;
    case kSbEventTypeLink: {
      const char* link = static_cast<const char*>(starboard_event->data);
      DispatchEventInternal(new base::DeepLinkEvent(link));
      break;
    }
    case kSbEventTypeAccessiblitySettingsChanged:
      DispatchEventInternal(new base::AccessibilitySettingsChangedEvent());
      break;
    default:
      DLOG(WARNING) << "Unhandled Starboard event of type: "
                    << starboard_event->type;
  }
}

void Application::OnNetworkEvent(const base::Event* event) {
  TRACE_EVENT0("cobalt::browser", "Application::OnNetworkEvent()");
  DCHECK(network_event_thread_checker_.CalledOnValidThread());
  const network::NetworkEvent* network_event =
      base::polymorphic_downcast<const network::NetworkEvent*>(event);
  if (network_event->type() == network::NetworkEvent::kDisconnection) {
    network_status_ = kDisconnectedNetworkStatus;
    ++network_disconnect_count_;
    browser_module_->Navigate(GURL("h5vcc://network-failure"));
  } else if (network_event->type() == network::NetworkEvent::kConnection) {
    network_status_ = kConnectedNetworkStatus;
    ++network_connect_count_;
    if (network_disconnect_count_ > 0) {
      DLOG(INFO) << "Got network connection event, reloading browser.";
      browser_module_->Reload();
    } else {
      DLOG(INFO) << "Got network connection event, NOT reloading browser.";
    }
  }
}

void Application::OnApplicationEvent(SbEventType event_type) {
  TRACE_EVENT0("cobalt::browser", "Application::OnApplicationEvent()");
  DCHECK(application_event_thread_checker_.CalledOnValidThread());
  switch (event_type) {
    case kSbEventTypeStop:
      DLOG(INFO) << "Got quit event.";
      app_status_ = kWillQuitAppStatus;
      Quit();
      DLOG(INFO) << "Finished quitting.";
      break;
    case kSbEventTypeStart:
      DLOG(INFO) << "Got start event.";
      app_status_ = kRunningAppStatus;
      browser_module_->Start();
      DLOG(INFO) << "Finished starting.";
      break;
    case kSbEventTypePause:
      DLOG(INFO) << "Got pause event.";
      app_status_ = kPausedAppStatus;
      ++app_pause_count_;
      browser_module_->Pause();
      DLOG(INFO) << "Finished pausing.";
      break;
    case kSbEventTypeUnpause:
      DLOG(INFO) << "Got unpause event.";
      app_status_ = kRunningAppStatus;
      ++app_unpause_count_;
      browser_module_->Unpause();
      DLOG(INFO) << "Finished unpausing.";
      break;
    case kSbEventTypeSuspend:
      DLOG(INFO) << "Got suspend event.";
      app_status_ = kSuspendedAppStatus;
      ++app_suspend_count_;
      browser_module_->Suspend();
      DLOG(INFO) << "Finished suspending.";
      break;
    case kSbEventTypeResume:
      DLOG(INFO) << "Got resume event.";
      app_status_ = kPausedAppStatus;
      ++app_resume_count_;
      browser_module_->Resume();
      DLOG(INFO) << "Finished resuming.";
      break;
#if SB_API_VERSION >= SB_LOW_MEMORY_EVENT_API_VERSION
    case kSbEventTypeLowMemory:
      DLOG(INFO) << "Got low memory event.";
      browser_module_->ReduceMemory();
      DLOG(INFO) << "Finished reducing memory usage.";
      break;
#endif  // SB_API_VERSION >= SB_LOW_MEMORY_EVENT_API_VERSION
    default:
      NOTREACHED() << "Unexpected event type: " << event_type;
      return;
  }
}

void Application::OnDeepLinkEvent(const base::Event* event) {
  TRACE_EVENT0("cobalt::browser", "Application::OnDeepLinkEvent()");
  const base::DeepLinkEvent* deep_link_event =
      base::polymorphic_downcast<const base::DeepLinkEvent*>(event);
  // TODO: Remove this when terminal application states are properly handled.
  if (deep_link_event->IsH5vccLink()) {
    browser_module_->Navigate(GURL(deep_link_event->link()));
  }
}

void Application::WebModuleRecreated() {
  TRACE_EVENT0("cobalt::browser", "Application::WebModuleRecreated()");
#if defined(ENABLE_WEBDRIVER)
  if (web_driver_module_) {
    web_driver_module_->OnWindowRecreated();
  }
#endif
}

Application::CValStats::CValStats()
    : free_cpu_memory("Memory.CPU.Free", 0,
                      "Total free application CPU memory remaining."),
      used_cpu_memory("Memory.CPU.Used", 0,
                      "Total CPU memory allocated via the app's allocators."),
      js_reserved_memory("Memory.JS", 0,
                         "The total memory that is reserved by the engine, "
                         "including the part that is actually occupied by "
                         "JS objects, and the part that is not yet."),
      app_start_time("Time.Cobalt.Start",
                     base::StartupTimer::StartTime().ToInternalValue(),
                     "Start time of the application in microseconds."),
      app_lifetime("Cobalt.Lifetime", base::TimeDelta(),
                   "Application lifetime in microseconds.") {
  if (SbSystemHasCapability(kSbSystemCapabilityCanQueryGPUMemoryStats)) {
    free_gpu_memory.emplace("Memory.GPU.Free", 0,
                            "Total free application GPU memory remaining.");
    used_gpu_memory.emplace("Memory.GPU.Used", 0,
                            "Total GPU memory allocated by the application.");
  }
}

void Application::RegisterUserLogs() {
  if (base::UserLog::IsRegistrationSupported()) {
    base::UserLog::Register(
        base::UserLog::kSystemLanguageStringIndex, "SystemLanguage",
        non_trivial_static_fields.Get().system_language.c_str(),
        non_trivial_static_fields.Get().system_language.size());

    base::UserLog::Register(base::UserLog::kAvailableMemoryIndex,
                            "AvailableMemory", &available_memory_,
                            sizeof(available_memory_));
    base::UserLog::Register(base::UserLog::kAppLifetimeIndex, "Lifetime(ms)",
                            &lifetime_in_ms_, sizeof(lifetime_in_ms_));
    base::UserLog::Register(base::UserLog::kAppStatusIndex, "AppStatus",
                            &app_status_, sizeof(app_status_));
    base::UserLog::Register(base::UserLog::kAppPauseCountIndex, "PauseCnt",
                            &app_pause_count_, sizeof(app_pause_count_));
    base::UserLog::Register(base::UserLog::kAppUnpauseCountIndex, "UnpauseCnt",
                            &app_unpause_count_, sizeof(app_unpause_count_));
    base::UserLog::Register(base::UserLog::kAppSuspendCountIndex, "SuspendCnt",
                            &app_suspend_count_, sizeof(app_suspend_count_));
    base::UserLog::Register(base::UserLog::kAppResumeCountIndex, "ResumeCnt",
                            &app_resume_count_, sizeof(app_resume_count_));
    base::UserLog::Register(base::UserLog::kNetworkStatusIndex,
                            "NetworkStatus", &network_status_,
                            sizeof(network_status_));
    base::UserLog::Register(base::UserLog::kNetworkConnectCountIndex,
                            "ConnectCnt", &network_connect_count_,
                            sizeof(network_connect_count_));
    base::UserLog::Register(base::UserLog::kNetworkDisconnectCountIndex,
                            "DisconnectCnt", &network_disconnect_count_,
                            sizeof(network_disconnect_count_));
  }
}

// NOTE: UserAgent registration is handled separately, as the value is not
// available when the app is first being constructed. Registration must happen
// each time the user agent is modified, because the string may be pointing
// to a new location on the heap.
void Application::UpdateAndMaybeRegisterUserAgent() {
  non_trivial_static_fields.Get().user_agent = browser_module_->GetUserAgent();
  DLOG(INFO) << "User Agent: " << non_trivial_static_fields.Get().user_agent;
  if (base::UserLog::IsRegistrationSupported()) {
    base::UserLog::Register(base::UserLog::kUserAgentStringIndex, "UserAgent",
                            non_trivial_static_fields.Get().user_agent.c_str(),
                            non_trivial_static_fields.Get().user_agent.size());
  }
}

void Application::UpdatePeriodicStats() {
  TRACE_EVENT0("cobalt::browser", "Application::UpdatePeriodicStats()");
  c_val_stats_.app_lifetime = base::StartupTimer::TimeElapsed();

  int64_t used_cpu_memory = SbSystemGetUsedCPUMemory();
  base::optional<int64_t> used_gpu_memory;
  if (SbSystemHasCapability(kSbSystemCapabilityCanQueryGPUMemoryStats)) {
    used_gpu_memory = SbSystemGetUsedGPUMemory();
  }

  available_memory_ =
      static_cast<ssize_t>(SbSystemGetTotalCPUMemory() - used_cpu_memory);
  c_val_stats_.free_cpu_memory = available_memory_;
  c_val_stats_.used_cpu_memory = used_cpu_memory;

  if (used_gpu_memory) {
    *c_val_stats_.free_gpu_memory =
        SbSystemGetTotalGPUMemory() - *used_gpu_memory;
    *c_val_stats_.used_gpu_memory = *used_gpu_memory;
  }

  c_val_stats_.js_reserved_memory =
      script::JavaScriptEngine::UpdateMemoryStatsAndReturnReserved();

  browser_module_->CheckMemory(used_cpu_memory, used_gpu_memory);
}

void Application::DispatchEventInternal(base::Event* event) {
  event_dispatcher_.DispatchEvent(make_scoped_ptr<base::Event>(event));
}

}  // namespace browser
}  // namespace cobalt
