// Copyright 2017 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/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.h"

#include <utility>
#include <vector>

#include "ash/public/cpp/scale_utility.h"
#include "ash/shell.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/arc/arc_session_manager.h"
#include "chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h"
#include "chrome/browser/chromeos/first_run/first_run.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
#include "chrome/browser/ui/app_list/arc/arc_pai_starter.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chromeos/chromeos_switches.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
#include "components/arc/arc_prefs.h"
#include "components/arc/arc_service_manager.h"
#include "components/arc/connection_holder.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "ui/accessibility/platform/ax_snapshot_node_android_platform.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/snapshot/snapshot.h"
#include "ui/wm/public/activation_client.h"
#include "url/gurl.h"

namespace arc {

namespace {

constexpr base::TimeDelta kAssistantStartedTimeout =
    base::TimeDelta::FromMinutes(1);
constexpr base::TimeDelta kWizardCompletedTimeout =
    base::TimeDelta::FromMinutes(1);

mojom::VoiceInteractionStructurePtr CreateVoiceInteractionStructure(
    const ui::AXSnapshotNodeAndroid& view_structure) {
  auto structure = mojom::VoiceInteractionStructure::New();
  structure->text = view_structure.text;
  structure->text_size = view_structure.text_size;

  structure->bold = view_structure.bold;
  structure->italic = view_structure.italic;
  structure->underline = view_structure.underline;
  structure->line_through = view_structure.line_through;
  structure->color = view_structure.color;
  structure->bgcolor = view_structure.bgcolor;

  structure->role = view_structure.role;

  structure->class_name = view_structure.class_name;
  structure->rect = view_structure.rect;

  if (view_structure.has_selection) {
    structure->selection = gfx::Range(view_structure.start_selection,
                                      view_structure.end_selection);
  }

  for (auto& child : view_structure.children)
    structure->children.push_back(CreateVoiceInteractionStructure(*child));

  return structure;
}

void RequestVoiceInteractionStructureCallback(
    ArcVoiceInteractionArcHomeService::GetVoiceInteractionStructureCallback
        callback,
    const gfx::Rect& bounds,
    const std::string& web_url,
    const base::string16& title,
    const ui::AXTreeUpdate& update) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // The assist structure starts with 2 dummy nodes: Url node and title
  // node. Then we attach all nodes in view hierarchy.
  auto root = mojom::VoiceInteractionStructure::New();
  root->rect = bounds;
  root->class_name = "android.view.dummy.root.WebUrl";
  root->text = base::UTF8ToUTF16(web_url);

  auto title_node = mojom::VoiceInteractionStructure::New();
  title_node->rect = gfx::Rect(bounds.size());
  title_node->class_name = "android.view.dummy.WebTitle";
  title_node->text = title;
  title_node->children.push_back(CreateVoiceInteractionStructure(
      *ui::AXSnapshotNodeAndroid::Create(update, false)));
  root->children.push_back(std::move(title_node));
  std::move(callback).Run(std::move(root));
}

// Singleton factory for ArcVoiceInteractionArcHomeService.
class ArcVoiceInteractionArcHomeServiceFactory
    : public internal::ArcBrowserContextKeyedServiceFactoryBase<
          ArcVoiceInteractionArcHomeService,
          ArcVoiceInteractionArcHomeServiceFactory> {
 public:
  // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
  static constexpr const char* kName =
      "ArcVoiceInteractionArcHomeServiceFactory";

  static ArcVoiceInteractionArcHomeServiceFactory* GetInstance() {
    return base::Singleton<ArcVoiceInteractionArcHomeServiceFactory>::get();
  }

 private:
  friend base::DefaultSingletonTraits<ArcVoiceInteractionArcHomeServiceFactory>;

  ArcVoiceInteractionArcHomeServiceFactory() {
    DependsOn(ArcAppListPrefsFactory::GetInstance());
    DependsOn(ArcVoiceInteractionFrameworkService::GetFactory());
  }
  ~ArcVoiceInteractionArcHomeServiceFactory() override = default;

  // BrowserContextKeyedServiceFactory override:
  KeyedService* BuildServiceInstanceFor(
      content::BrowserContext* context) const override {
    if (!chromeos::switches::IsVoiceInteractionEnabled())
      return nullptr;
    return ArcBrowserContextKeyedServiceFactoryBase::BuildServiceInstanceFor(
        context);
  }
};

}  // namespace

// static
const char ArcVoiceInteractionArcHomeService::kAssistantPackageName[] =
    "com.google.android.googlequicksearchbox";

// static
ArcVoiceInteractionArcHomeService*
ArcVoiceInteractionArcHomeService::GetForBrowserContext(
    content::BrowserContext* context) {
  return ArcVoiceInteractionArcHomeServiceFactory::GetForBrowserContext(
      context);
}

ArcVoiceInteractionArcHomeService::ArcVoiceInteractionArcHomeService(
    content::BrowserContext* context,
    ArcBridgeService* bridge_service)
    : context_(context),
      arc_bridge_service_(bridge_service),
      assistant_started_timeout_(kAssistantStartedTimeout),
      wizard_completed_timeout_(kWizardCompletedTimeout) {
  arc_bridge_service_->voice_interaction_arc_home()->SetHost(this);
  arc_bridge_service_->voice_interaction_arc_home()->AddObserver(this);
  ArcSessionManager::Get()->AddObserver(this);
}

ArcVoiceInteractionArcHomeService::~ArcVoiceInteractionArcHomeService() =
    default;

void ArcVoiceInteractionArcHomeService::Shutdown() {
  ResetTimeouts();
  arc_bridge_service_->voice_interaction_arc_home()->RemoveObserver(this);
  arc_bridge_service_->voice_interaction_arc_home()->SetHost(nullptr);
  ArcSessionManager::Get()->RemoveObserver(this);
}

void ArcVoiceInteractionArcHomeService::OnArcPlayStoreEnabledChanged(
    bool enabled) {
  if (!pending_pai_lock_)
    return;

  pending_pai_lock_ = false;
  LockPai();
}

void ArcVoiceInteractionArcHomeService::LockPai() {
  ResetTimeouts();
  arc::ArcPaiStarter* pai_starter =
      arc::ArcSessionManager::Get()->pai_starter();
  if (!pai_starter) {
    DLOG(ERROR) << "There is no PAI starter.";
    // We could be starting before ARC session is started when user initiated
    // voice interaction first before ARC is enabled. We will remember this
    // and wait for ARC session started to try locking again.
    pending_pai_lock_ = true;
    return;
  }
  pai_starter->AcquireLock();
}

void ArcVoiceInteractionArcHomeService::UnlockPai() {
  ResetTimeouts();
  arc::ArcPaiStarter* pai_starter =
      arc::ArcSessionManager::Get()->pai_starter();
  if (!pai_starter || !pai_starter->locked())
    return;
  pai_starter->ReleaseLock();
}

void ArcVoiceInteractionArcHomeService::OnAssistantStarted() {
  VLOG(1) << "Assistant flow started";
  LockPai();
}

void ArcVoiceInteractionArcHomeService::OnAssistantAppRequested() {
  VLOG(1) << "Assistant app start request";

  ResetTimeouts();

  ArcAppListPrefs::Get(context_)->AddObserver(this);

  assistant_started_timer_.Start(
      FROM_HERE, assistant_started_timeout_,
      base::Bind(&ArcVoiceInteractionArcHomeService::OnAssistantStartTimeout,
                 base::Unretained(this)));
}

void ArcVoiceInteractionArcHomeService::OnAssistantCanceled() {
  VLOG(1) << "Assistant flow canceled";
  UnlockPai();
}

void ArcVoiceInteractionArcHomeService::OnTaskCreated(
    int32_t task_id,
    const std::string& package_name,
    const std::string& activity,
    const std::string& intent) {
  if (package_name != kAssistantPackageName)
    return;

  VLOG(1) << "Assistant app created";

  DCHECK_EQ(-1, assistant_task_id_);
  assistant_task_id_ = task_id;
  assistant_started_timer_.Stop();
}

void ArcVoiceInteractionArcHomeService::OnTaskDestroyed(int32_t task_id) {
  if (task_id != assistant_task_id_)
    return;

  VLOG(1) << "Assistant app exited";

  ResetTimeouts();
  wizard_completed_timer_.Start(
      FROM_HERE, wizard_completed_timeout_,
      base::Bind(&ArcVoiceInteractionArcHomeService::OnWizardCompleteTimeout,
                 base::Unretained(this)));
}

void ArcVoiceInteractionArcHomeService::ResetTimeouts() {
  ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(context_);
  if (arc_prefs)
    arc_prefs->RemoveObserver(this);

  assistant_started_timer_.Stop();
  wizard_completed_timer_.Stop();
}

void ArcVoiceInteractionArcHomeService::OnAssistantStartTimeout() {
  LOG(WARNING) << "Failed to start Assistant app.";
  UnlockPai();
}

void ArcVoiceInteractionArcHomeService::OnWizardCompleteTimeout() {
  LOG(WARNING) << "Assistant app was not completed successfully.";
  UnlockPai();
}

void ArcVoiceInteractionArcHomeService::OnConnectionClosed() {
  VLOG(1) << "Voice interaction instance is closed.";
  UnlockPai();
}

void ArcVoiceInteractionArcHomeService::GetVoiceInteractionStructure(
    GetVoiceInteractionStructureCallback callback) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  PrefService* prefs = Profile::FromBrowserContext(context_)->GetPrefs();
  auto* framework_service =
      ArcVoiceInteractionFrameworkService::GetForBrowserContext(context_);
  if (!framework_service->ValidateTimeSinceUserInteraction() ||
      !prefs->GetBoolean(prefs::kVoiceInteractionEnabled) ||
      !prefs->GetBoolean(prefs::kVoiceInteractionContextEnabled)) {
    std::move(callback).Run(mojom::VoiceInteractionStructure::New());
    return;
  }
  Browser* browser = BrowserList::GetInstance()->GetLastActive();
  if (!browser || !browser->window()->IsActive()) {
    // TODO(muyuanli): retrieve context for apps.
    LOG(ERROR) << "Retrieving context from apps is not implemented.";
    std::move(callback).Run(mojom::VoiceInteractionStructure::New());
    return;
  }

  VLOG(1) << "Retrieving voice interaction context";

  content::WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  // Do not process incognito tab.
  if (web_contents->GetBrowserContext()->IsOffTheRecord()) {
    std::move(callback).Run(mojom::VoiceInteractionStructure::New());
    return;
  }

  auto transform = browser->window()
                       ->GetNativeWindow()
                       ->GetRootWindow()
                       ->GetHost()
                       ->GetRootTransform();
  float scale_factor = ash::GetScaleFactorForTransform(transform);
  web_contents->RequestAXTreeSnapshot(base::BindOnce(
      &RequestVoiceInteractionStructureCallback, std::move(callback),
      gfx::ConvertRectToPixel(scale_factor, browser->window()->GetBounds()),
      web_contents->GetLastCommittedURL().spec(), web_contents->GetTitle()));
}

void ArcVoiceInteractionArcHomeService::OnVoiceInteractionOobeSetupComplete() {
  VLOG(1) << "Assistant wizard is completed.";
  UnlockPai();
  chromeos::first_run::MaybeLaunchDialogImmediately();
}

// static
mojom::VoiceInteractionStructurePtr
ArcVoiceInteractionArcHomeService::CreateVoiceInteractionStructureForTesting(
    const ui::AXSnapshotNodeAndroid& view_structure) {
  return CreateVoiceInteractionStructure(view_structure);
}

}  // namespace arc
