// Copyright (c) 2012 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/test/chromedriver/commands.h"

#include <algorithm>
#include <list>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/memory/linked_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "base/values.h"
#include "chrome/test/chromedriver/capabilities.h"
#include "chrome/test/chromedriver/chrome/chrome.h"
#include "chrome/test/chromedriver/chrome/status.h"
#include "chrome/test/chromedriver/chrome/version.h"
#include "chrome/test/chromedriver/logging.h"
#include "chrome/test/chromedriver/session.h"
#include "chrome/test/chromedriver/session_thread_map.h"
#include "chrome/test/chromedriver/util.h"

void ExecuteGetStatus(
    const base::DictionaryValue& params,
    const std::string& session_id,
    const CommandCallback& callback) {
  base::DictionaryValue build;
  build.SetString("version", "alpha");

  base::DictionaryValue os;
  os.SetString("name", base::SysInfo::OperatingSystemName());
  os.SetString("version", base::SysInfo::OperatingSystemVersion());
  os.SetString("arch", base::SysInfo::OperatingSystemArchitecture());

  base::DictionaryValue info;
  info.Set("build", build.DeepCopy());
  info.Set("os", os.DeepCopy());
  callback.Run(
      Status(kOk), scoped_ptr<base::Value>(info.DeepCopy()), std::string());
}

void ExecuteCreateSession(
    SessionThreadMap* session_thread_map,
    const Command& init_session_cmd,
    const base::DictionaryValue& params,
    const std::string& session_id,
    const CommandCallback& callback) {
  std::string new_id = session_id;
  if (new_id.empty())
    new_id = GenerateId();
  scoped_ptr<Session> session(new Session(new_id));
  scoped_ptr<base::Thread> thread(new base::Thread(new_id));
  if (!thread->Start()) {
    callback.Run(
        Status(kUnknownError, "failed to start a thread for the new session"),
        scoped_ptr<base::Value>(),
        std::string());
    return;
  }

  thread->message_loop()->PostTask(
      FROM_HERE, base::Bind(&SetThreadLocalSession, base::Passed(&session)));
  session_thread_map
      ->insert(std::make_pair(new_id, make_linked_ptr(thread.release())));
  init_session_cmd.Run(params, new_id, callback);
}

namespace {

void OnSessionQuit(const base::WeakPtr<size_t>& quit_remaining_count,
                   const base::Closure& all_quit_func,
                   const Status& status,
                   scoped_ptr<base::Value> value,
                   const std::string& session_id) {
  // |quit_remaining_count| may no longer be valid if a timeout occurred.
  if (!quit_remaining_count)
    return;

  (*quit_remaining_count)--;
  if (!*quit_remaining_count)
    all_quit_func.Run();
}

}  // namespace

void ExecuteQuitAll(
    const Command& quit_command,
    SessionThreadMap* session_thread_map,
    const base::DictionaryValue& params,
    const std::string& session_id,
    const CommandCallback& callback) {
  size_t quit_remaining_count = session_thread_map->size();
  base::WeakPtrFactory<size_t> weak_ptr_factory(&quit_remaining_count);
  if (!quit_remaining_count) {
    callback.Run(Status(kOk), scoped_ptr<base::Value>(), session_id);
    return;
  }
  base::RunLoop run_loop;
  for (SessionThreadMap::const_iterator iter = session_thread_map->begin();
       iter != session_thread_map->end();
       ++iter) {
    quit_command.Run(params,
                     iter->first,
                     base::Bind(&OnSessionQuit,
                                weak_ptr_factory.GetWeakPtr(),
                                run_loop.QuitClosure()));
  }
  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromSeconds(10));
  // Uses a nested run loop to block this thread until all the quit
  // commands have executed, or the timeout expires.
  base::MessageLoop::current()->SetNestableTasksAllowed(true);
  run_loop.Run();
  callback.Run(Status(kOk), scoped_ptr<base::Value>(), session_id);
}

namespace {

void TerminateSessionThreadOnCommandThread(SessionThreadMap* session_thread_map,
                                           const std::string& session_id) {
  session_thread_map->erase(session_id);
}

void ExecuteSessionCommandOnSessionThread(
    const char* command_name,
    const SessionCommand& command,
    bool return_ok_without_session,
    scoped_ptr<base::DictionaryValue> params,
    scoped_refptr<base::SingleThreadTaskRunner> cmd_task_runner,
    const CommandCallback& callback_on_cmd,
    const base::Closure& terminate_on_cmd) {
  Session* session = GetThreadLocalSession();
  if (!session) {
    cmd_task_runner->PostTask(
        FROM_HERE,
        base::Bind(callback_on_cmd,
                   Status(return_ok_without_session ? kOk : kNoSuchSession),
                   base::Passed(scoped_ptr<base::Value>()),
                   std::string()));
    return;
  }

  if (IsVLogOn(0)) {
    VLOG(0) << "COMMAND " << command_name << " "
            << FormatValueForDisplay(*params);
  }

  // Notify |session|'s |CommandListener|s of the command.
  NotifySessionListenersBeforeCommand(session, command_name);

  scoped_ptr<base::Value> value;
  Status status = command.Run(session, *params, &value);

  if (status.IsError() && session->chrome) {
    if (!session->quit && session->chrome->HasCrashedWebView()) {
      session->quit = true;
      std::string message("session deleted because of page crash");
      if (!session->detach) {
        Status quit_status = session->chrome->Quit();
        if (quit_status.IsError())
          message += ", but failed to kill browser:" + quit_status.message();
      }
      status = Status(kUnknownError, message, status);
    } else if (status.code() == kDisconnected) {
      // Some commands, like clicking a button or link which closes the window,
      // may result in a kDisconnected error code.
      std::list<std::string> web_view_ids;
      Status status_tmp = session->chrome->GetWebViewIds(&web_view_ids);
      if (status_tmp.IsError() && status_tmp.code() != kChromeNotReachable) {
        status.AddDetails(
            "failed to check if window was closed: " + status_tmp.message());
      } else if (std::find(web_view_ids.begin(),
                           web_view_ids.end(),
                           session->window) == web_view_ids.end()) {
        status = Status(kOk);
      }
    }
    if (status.IsError()) {
      const BrowserInfo* browser_info = session->chrome->GetBrowserInfo();
      status.AddDetails("Session info: " + browser_info->browser_name + "=" +
                        browser_info->browser_version);
    }
  }

  if (IsVLogOn(0)) {
    std::string result;
    if (status.IsError()) {
      result = status.message();
    } else if (value) {
      result = FormatValueForDisplay(*value);
    }
    VLOG(0) << "RESPONSE " << command_name
            << (result.length() ? " " + result : "");
  }

  if (status.IsOk() && session->auto_reporting_enabled) {
    std::string message = session->GetFirstBrowserError();
    if (!message.empty())
      status = Status(kUnknownError, message);
  }

  cmd_task_runner->PostTask(
      FROM_HERE,
      base::Bind(callback_on_cmd, status, base::Passed(&value), session->id));

  if (session->quit) {
    SetThreadLocalSession(scoped_ptr<Session>());
    delete session;
    cmd_task_runner->PostTask(FROM_HERE, terminate_on_cmd);
  }
}

}  // namespace

void ExecuteSessionCommand(
    SessionThreadMap* session_thread_map,
    const char* command_name,
    const SessionCommand& command,
    bool return_ok_without_session,
    const base::DictionaryValue& params,
    const std::string& session_id,
    const CommandCallback& callback) {
  SessionThreadMap::iterator iter = session_thread_map->find(session_id);
  if (iter == session_thread_map->end()) {
    Status status(return_ok_without_session ? kOk : kNoSuchSession);
    callback.Run(status, scoped_ptr<base::Value>(), session_id);
  } else {
    iter->second->message_loop()
        ->PostTask(FROM_HERE,
                   base::Bind(&ExecuteSessionCommandOnSessionThread,
                              command_name,
                              command,
                              return_ok_without_session,
                              base::Passed(make_scoped_ptr(params.DeepCopy())),
                              base::MessageLoopProxy::current(),
                              callback,
                              base::Bind(&TerminateSessionThreadOnCommandThread,
                                         session_thread_map,
                                         session_id)));
  }
}

namespace internal {

void CreateSessionOnSessionThreadForTesting(const std::string& id) {
  SetThreadLocalSession(make_scoped_ptr(new Session(id)));
}

}  // namespace internal
