// Copyright 2019 The Fuchsia 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 "src/ui/a11y/lib/screen_reader/explore_action.h"

#include <lib/fit/bridge.h>
#include <lib/fit/promise.h>
#include <lib/syslog/cpp/macros.h>

#include <cstdint>

#include "src/ui/a11y/lib/screen_reader/screen_reader.h"
#include "src/ui/a11y/lib/screen_reader/screen_reader_action.h"
#include "src/ui/a11y/lib/screen_reader/util/util.h"

namespace a11y {
namespace {
using fuchsia::accessibility::semantics::Hit;
using fuchsia::accessibility::tts::Utterance;

}  // namespace

ExploreAction::ExploreAction(ActionContext* context, ScreenReaderContext* screen_reader_context)
    : ScreenReaderAction(context, screen_reader_context) {}
ExploreAction::~ExploreAction() = default;

fit::promise<Hit> ExploreAction::ExecuteHitTestingPromise(const ActionData& process_data) {
  fit::bridge<Hit> bridge;
  ExecuteHitTesting(action_context_, process_data,
                    [completer = std::move(bridge.completer)](Hit hit) mutable {
                      if (!hit.has_node_id()) {
                        return completer.complete_error();
                      }
                      completer.complete_ok(std::move(hit));
                    });

  return bridge.consumer.promise_or(fit::error());
}

fit::result<uint32_t> ExploreAction::SelectDescribableNodePromise(zx_koid_t view_koid, Hit& hit) {
  if (!hit.has_node_id()) {
    return fit::error();
  }

  auto hit_test_result_node =
      action_context_->semantics_source->GetSemanticNode(view_koid, hit.node_id());
  if (!hit_test_result_node || !hit_test_result_node->has_node_id()) {
    FX_LOGS(WARNING) << "Invalid hit test result.";
    return fit::error();
  }

  auto node_to_return = hit_test_result_node;
  while (node_to_return && !NodeIsDescribable(node_to_return)) {
    FX_DCHECK(node_to_return->has_node_id());
    node_to_return =
        action_context_->semantics_source->GetParentNode(view_koid, node_to_return->node_id());
  }

  if (node_to_return && node_to_return->has_node_id()) {
    return fit::ok(node_to_return->node_id());
  }

  FX_LOGS(WARNING) << "No describable ancestor found for node " << hit_test_result_node->node_id();
  return fit::error();
}

fit::promise<> ExploreAction::SetA11yFocusOrStopPromise(ScreenReaderContext::ScreenReaderMode mode,
                                                        zx_koid_t view_koid, uint32_t node_id) {
  return fit::make_promise([this, mode, view_koid, node_id]() mutable -> fit::promise<> {
    if (mode == ScreenReaderContext::ScreenReaderMode::kContinuousExploration) {
      // If the new a11y focus to be set is the same as the existing one during a
      // continuous exploration, this means that the same node would be spoken
      // multiple times. Check if the focus is new before continuing.
      auto* a11y_focus_manager = screen_reader_context_->GetA11yFocusManager();
      auto focus = a11y_focus_manager->GetA11yFocus();
      if (!focus) {
        return fit::make_error_promise();
      }
      if (focus->view_ref_koid == view_koid && focus->node_id == node_id) {
        return fit::make_error_promise();
      }
    }
    return SetA11yFocusPromise(node_id, view_koid);
  });
}

void ExploreAction::Run(ActionData process_data) {
  auto promise = ExecuteHitTestingPromise(process_data)
                     .and_then([this, view_koid = process_data.current_view_koid](
                                   Hit& hit) mutable -> fit::result<uint32_t> {
                       return SelectDescribableNodePromise(view_koid, hit);
                     })
                     .and_then([this, view_koid = process_data.current_view_koid,
                                mode = screen_reader_context_->mode()](
                                   uint32_t& node_id) mutable -> fit::promise<> {
                       return SetA11yFocusOrStopPromise(mode, view_koid, node_id);
                     })
                     .and_then([this]() mutable -> fit::result<A11yFocusManager::A11yFocusInfo> {
                       auto* a11y_focus_manager = screen_reader_context_->GetA11yFocusManager();
                       auto focus = a11y_focus_manager->GetA11yFocus();
                       if (!focus) {
                         return fit::error();
                       }
                       return fit::ok(std::move(*focus));
                     })
                     .and_then([this](const A11yFocusManager::A11yFocusInfo& focus) mutable {
                       return BuildSpeechTaskFromNodePromise(focus.view_ref_koid, focus.node_id);
                     })
                     // Cancel any promises if this class goes out of scope.
                     .wrap_with(scope_);
  auto* executor = screen_reader_context_->executor();
  executor->schedule_task(std::move(promise));
}

}  // namespace a11y
