// Copyright 2013 The Flutter 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 <fuchsia/ui/views/cpp/fidl.h>
#include <gtest/gtest.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>

#include "focus_delegate.h"
#include "tests/fakes/focuser.h"
#include "tests/fakes/platform_message.h"
#include "tests/fakes/view_ref_focused.h"
#include "third_party/rapidjson/include/rapidjson/document.h"

rapidjson::Value ParsePlatformMessage(std::string json) {
  rapidjson::Document document;
  document.Parse(json);
  if (document.HasParseError() || !document.IsObject()) {
    FML_LOG(ERROR) << "Could not parse document";
    return rapidjson::Value();
  }
  return document.GetObject();
}

namespace flutter_runner::testing {

class FocusDelegateTest : public ::testing::Test {
 protected:
  FocusDelegateTest() : loop_(&kAsyncLoopConfigAttachToCurrentThread) {}

  void RunLoopUntilIdle() { loop_.RunUntilIdle(); }

  void SetUp() override {
    vrf_ = std::make_unique<FakeViewRefFocused>();
    focuser_ = std::make_unique<FakeFocuser>();
    focus_delegate_ = std::make_unique<FocusDelegate>(
        vrf_bindings.AddBinding(vrf_.get()),
        focuser_bindings.AddBinding(focuser_.get()));
  }

  void TearDown() override {
    vrf_bindings.CloseAll();
    focuser_bindings.CloseAll();
    loop_.Quit();
    loop_.ResetQuit();
  }

  std::unique_ptr<FakeViewRefFocused> vrf_;
  std::unique_ptr<FakeFocuser> focuser_;
  std::unique_ptr<FocusDelegate> focus_delegate_;

 private:
  async::Loop loop_;
  fidl::BindingSet<ViewRefFocused> vrf_bindings;
  fidl::BindingSet<Focuser> focuser_bindings;

  FML_DISALLOW_COPY_AND_ASSIGN(FocusDelegateTest);
};

// Tests that WatchLoop() should callback and complete PlatformMessageResponses
// correctly, given a series of vrf invocations.
TEST_F(FocusDelegateTest, WatchCallbackSeries) {
  std::vector<bool> vrf_states{false, true,  true, false,
                               true,  false, true, true};
  std::size_t vrf_index = 0;
  std::size_t callback_index = 0;
  focus_delegate_->WatchLoop([&](bool focus_state) {
    // Make sure the focus state that FocusDelegate gives us is consistent with
    // what was fired from the vrf.
    EXPECT_EQ(vrf_states[callback_index], focus_state);

    // View.focus.getCurrent should complete with the current (up to date) focus
    // state.
    auto response = FakePlatformMessageResponse::Create();
    EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
        ParsePlatformMessage("{\"method\":\"View.focus.getCurrent\"}"),
        response));
    response->ExpectCompleted(focus_state ? "[true]" : "[false]");

    // Ensure this callback always happens in lockstep with
    // vrf_->ScheduleCallback.
    EXPECT_EQ(vrf_index, callback_index++);
  });

  // Subsequent WatchLoop calls should not be respected.
  focus_delegate_->WatchLoop([](bool _) {
    ADD_FAILURE() << "Subsequent WatchLoops should not be respected!";
  });

  do {
    // Ensure the next focus state is handled correctly.
    auto response1 = FakePlatformMessageResponse::Create();
    EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
        ParsePlatformMessage("{\"method\":\"View.focus.getNext\"}"),
        response1));

    // Since there's already an outstanding PlatformMessageResponse, this one
    // should be completed null.
    auto response2 = FakePlatformMessageResponse::Create();
    EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
        ParsePlatformMessage("{\"method\":\"View.focus.getNext\"}"),
        response2));
    response2->ExpectCompleted("[null]");

    // Post watch events and trigger the next vrf event.
    RunLoopUntilIdle();
    vrf_->ScheduleCallback(vrf_states[vrf_index]);
    RunLoopUntilIdle();

    // Next focus state should be completed by now.
    response1->ExpectCompleted(vrf_states[vrf_index] ? "[true]" : "[false]");

    // Check View.focus.getCurrent again, and increment vrf_index since we move
    // on to the next focus state.
    auto response3 = FakePlatformMessageResponse::Create();
    EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
        ParsePlatformMessage("{\"method\":\"View.focus.getCurrent\"}"),
        response3));
    response3->ExpectCompleted(vrf_states[vrf_index++] ? "[true]" : "[false]");

    // vrf_->times_watched should always be 1 more than the amount of vrf events
    // emitted.
    EXPECT_EQ(vrf_index + 1, vrf_->times_watched);
  } while (vrf_index < vrf_states.size());
}

// Tests that HandlePlatformMessage() completes a "View.focus.request" response
// with a non-error status code.
TEST_F(FocusDelegateTest, RequestFocusTest) {
  // This "Mock" ViewRef serves as the target for the RequestFocus operation.
  auto mock_view_ref_pair = scenic::ViewRefPair::New();
  // Create the platform message request.
  std::ostringstream message;
  message << "{"
          << "    \"method\":\"View.focus.request\","
          << "    \"args\": {"
          << "       \"viewRef\":"
          << mock_view_ref_pair.view_ref.reference.get() << "    }"
          << "}";

  // Dispatch the plaform message request with an expected completion response.
  auto response = FakePlatformMessageResponse::Create();
  EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
      ParsePlatformMessage(message.str()), response));
  RunLoopUntilIdle();

  response->ExpectCompleted("[0]");
  EXPECT_TRUE(focuser_->request_focus_called());
}

// Tests that HandlePlatformMessage() completes a "View.focus.request" response
// with a Error::DENIED status code.
TEST_F(FocusDelegateTest, RequestFocusFailTest) {
  // This "Mock" ViewRef serves as the target for the RequestFocus operation.
  auto mock_view_ref_pair = scenic::ViewRefPair::New();
  // We're testing the focus failure case.
  focuser_->fail_request_focus();
  // Create the platform message request.
  std::ostringstream message;
  message << "{"
          << "    \"method\":\"View.focus.request\","
          << "    \"args\": {"
          << "       \"viewRef\":"
          << mock_view_ref_pair.view_ref.reference.get() << "    }"
          << "}";

  // Dispatch the plaform message request with an expected completion response.
  auto response = FakePlatformMessageResponse::Create();
  EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
      ParsePlatformMessage(message.str()), response));
  RunLoopUntilIdle();

  response->ExpectCompleted(
      "[" +
      std::to_string(
          static_cast<std::underlying_type_t<fuchsia::ui::views::Error>>(
              fuchsia::ui::views::Error::DENIED)) +
      "]");
  EXPECT_TRUE(focuser_->request_focus_called());
}

}  // namespace flutter_runner::testing
