// Copyright (c) 2016 The Chromium Embedded Framework 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 "include/base/cef_bind.h"
#include "include/cef_accessibility_handler.h"
#include "include/cef_parser.h"
#include "include/cef_waitable_event.h"
#include "include/wrapper/cef_closure_task.h"
#include "tests/ceftests/test_handler.h"
#include "tests/ceftests/test_util.h"
#include "tests/gtest/include/gtest/gtest.h"

namespace {

const char kTestUrl[] = "https://tests/AccessibilityTestHandler";
const char kTipText[] = "Also known as User ID";

// Default OSR widget size.
const int kOsrWidth = 600;
const int kOsrHeight = 400;

// Test type.
enum AccessibilityTestType {
  // Enabling Accessibility should trigger the AccessibilityHandler callback
  // with Accessibility tree details
  TEST_ENABLE,
  // Disabling Accessibility should disable accessibility notification changes
  TEST_DISABLE,
  // Focus change on element should trigger Accessibility focus event
  TEST_FOCUS_CHANGE,
  // Hide/Show etc should trigger Location Change callbacks
  TEST_LOCATION_CHANGE
};

class AccessibilityTestHandler : public TestHandler,
                                 public CefRenderHandler,
                                 public CefAccessibilityHandler {
 public:
  AccessibilityTestHandler(const AccessibilityTestType& type)
      : test_type_(type), edit_box_id_(-1), accessibility_disabled_(false) {}

  CefRefPtr<CefAccessibilityHandler> GetAccessibilityHandler() override {
    return this;
  }

  CefRefPtr<CefRenderHandler> GetRenderHandler() override { return this; }

  // Cef Renderer Handler Methods
  void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) override {
    rect = CefRect(0, 0, kOsrWidth, kOsrHeight);
  }

  bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
                     CefScreenInfo& screen_info) override {
    screen_info.rect = CefRect(0, 0, kOsrWidth, kOsrHeight);
    screen_info.available_rect = screen_info.rect;
    return true;
  }

  void OnPaint(CefRefPtr<CefBrowser> browser,
               CefRenderHandler::PaintElementType type,
               const CefRenderHandler::RectList& dirtyRects,
               const void* buffer,
               int width,
               int height) override {
    // Do nothing.
  }

  void RunTest() override {
    std::string html =
        "<html><head><title>AccessibilityTest</title></head>"
        "<body><span id='tipspan' role='tooltip' style='color:red;"
        "margin:20px'>";
    html += kTipText;
    html +=
        "</span>"
        "<input id='editbox' type='text' aria-describedby='tipspan' "
        "value='editbox' size='25px'/><input id='button' type='button' "
        "value='button' style='margin:20px'/></body></html>";
    AddResource(kTestUrl, html, "text/html");

    // Create the browser
    CreateOSRBrowser(kTestUrl);

    // Time out the test after a reasonable period of time.
    SetTestTimeout(5000);
  }

  void OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame,
                 int httpStatusCode) override {
    // Enable Accessibility
    browser->GetHost()->SetAccessibilityState(STATE_ENABLED);
    switch (test_type_) {
      case TEST_ENABLE: {
        // This should trigger OnAccessibilityTreeChange
        // And update will be validated
      } break;
      case TEST_DISABLE: {
        // Post a delayed task to disable Accessibility
        CefPostDelayedTask(
            TID_UI,
            base::Bind(&AccessibilityTestHandler::DisableAccessibility, this,
                       browser),
            200);
      } break;
      // Delayed task will posted later after we have initial details
      case TEST_FOCUS_CHANGE: {
      } break;
      case TEST_LOCATION_CHANGE: {
      } break;
    }
  }

  void OnAccessibilityTreeChange(CefRefPtr<CefValue> value) override {
    switch (test_type_) {
      case TEST_ENABLE: {
        TestEnableAccessibilityUpdate(value);
      } break;
      case TEST_DISABLE: {
        // Once Accessibility is disabled in the delayed Task
        // We should not reach here
        EXPECT_FALSE(accessibility_disabled_);
      } break;
      case TEST_LOCATION_CHANGE: {
        // find accessibility id of the edit box, before setting focus
        if (edit_box_id_ == -1) {
          CefRefPtr<CefDictionaryValue> update, event;
          GetFirstUpdateAndEvent(value, update, event);
          EXPECT_TRUE(update.get());

          // Ignore other events.
          if (!event.get() ||
              event->GetString("event_type") != "layoutComplete") {
            break;
          }

          SetEditBoxIdAndRect(update);
          EXPECT_NE(edit_box_id_, -1);
          // Post a delayed task to hide the span and trigger location change
          CefPostDelayedTask(TID_UI,
                             base::Bind(&AccessibilityTestHandler::HideEditBox,
                                        this, GetBrowser()),
                             200);
        }
      } break;
      case TEST_FOCUS_CHANGE: {
        // find accessibility id of the edit box, before setting focus
        if (edit_box_id_ == -1) {
          CefRefPtr<CefDictionaryValue> update, event;
          GetFirstUpdateAndEvent(value, update, event);
          EXPECT_TRUE(update.get());

          // Ignore other events.
          if (!event.get() ||
              event->GetString("event_type") != "layoutComplete") {
            break;
          }

          // Now post a delayed task to trigger focus to edit box
          SetEditBoxIdAndRect(update);
          EXPECT_NE(edit_box_id_, -1);

          CefPostDelayedTask(
              TID_UI,
              base::Bind(&AccessibilityTestHandler::SetFocusOnEditBox, this,
                         GetBrowser()),
              200);
        } else {
          // Retrieve the "focus" event.
          CefRefPtr<CefDictionaryValue> event;
          if (!GetFirstMatchingEvent(value, "focus", event))
            return;
          EXPECT_TRUE(event.get());

          // Verify that focus is set to expected element edit_box.
          EXPECT_EQ(edit_box_id_, event->GetInt("id"));

          // Now Post a delayed task to destroy the test giving
          // sufficient time for any accessibility updates to come through
          CefPostDelayedTask(
              TID_UI, base::Bind(&AccessibilityTestHandler::DestroyTest, this),
              500);
        }
      } break;
    }
  }

  void OnAccessibilityLocationChange(CefRefPtr<CefValue> value) override {
    if (test_type_ == TEST_LOCATION_CHANGE) {
      EXPECT_NE(edit_box_id_, -1);
      EXPECT_TRUE(value.get());

      // Change has a valid list
      EXPECT_EQ(VTYPE_LIST, value->GetType());
      CefRefPtr<CefListValue> list = value->GetList();
      EXPECT_TRUE(list.get());

      got_accessibility_location_change_.yes();
    }

    if (got_hide_edit_box_) {
      // Now destroy the test.
      CefPostTask(TID_UI,
                  base::Bind(&AccessibilityTestHandler::DestroyTest, this));
    }
  }

 private:
  void CreateOSRBrowser(const CefString& url) {
    CefWindowInfo windowInfo;
    CefBrowserSettings settings;

#if defined(OS_WIN)
    windowInfo.SetAsWindowless(GetDesktopWindow());
#elif defined(OS_MACOSX)
    windowInfo.SetAsWindowless(kNullWindowHandle);
#elif defined(OS_LINUX)
    windowInfo.SetAsWindowless(kNullWindowHandle);
#else
#error "Unsupported platform"
#endif
    CefBrowserHost::CreateBrowser(windowInfo, this, url, settings, nullptr,
                                  nullptr);
  }

  void HideEditBox(CefRefPtr<CefBrowser> browser) {
    // Hide the edit box.
    // This should trigger Location update if enabled
    browser->GetMainFrame()->ExecuteJavaScript(
        "document.getElementById('editbox').style.display = 'none';", kTestUrl,
        0);

    got_hide_edit_box_.yes();
  }

  void SetFocusOnEditBox(CefRefPtr<CefBrowser> browser) {
    // Set focus on edit box
    // This should trigger accessibility update if enabled
    browser->GetMainFrame()->ExecuteJavaScript(
        "document.getElementById('editbox').focus();", kTestUrl, 0);
  }

  void DisableAccessibility(CefRefPtr<CefBrowser> browser) {
    browser->GetHost()->SetAccessibilityState(STATE_DISABLED);
    accessibility_disabled_ = true;
    // Set focus on edit box
    SetFocusOnEditBox(browser);

    // Now Post a delayed task to destroy the test
    // giving sufficient time for any accessibility updates to come through
    CefPostDelayedTask(
        TID_UI, base::Bind(&AccessibilityTestHandler::DestroyTest, this), 500);
  }

  static CefRefPtr<CefListValue> GetUpdateList(CefRefPtr<CefValue> value) {
    EXPECT_TRUE(value.get());
    EXPECT_EQ(value->GetType(), VTYPE_DICTIONARY);
    CefRefPtr<CefDictionaryValue> topLevel = value->GetDictionary();
    EXPECT_TRUE(topLevel.get());

    return topLevel->GetList("updates");
  }

  static size_t GetUpdateListSize(CefRefPtr<CefValue> value) {
    CefRefPtr<CefListValue> updates = GetUpdateList(value);
    if (updates)
      return updates->GetSize();
    return 0U;
  }

  static CefRefPtr<CefDictionaryValue> GetUpdateValue(CefRefPtr<CefValue> value,
                                                      size_t index) {
    CefRefPtr<CefListValue> updates = GetUpdateList(value);
    if (!updates)
      return nullptr;
    EXPECT_LT(index, updates->GetSize());
    CefRefPtr<CefDictionaryValue> update = updates->GetDictionary(index);
    EXPECT_TRUE(update);
    return update;
  }

  static CefRefPtr<CefListValue> GetEventList(CefRefPtr<CefValue> value) {
    EXPECT_TRUE(value.get());
    EXPECT_EQ(value->GetType(), VTYPE_DICTIONARY);
    CefRefPtr<CefDictionaryValue> topLevel = value->GetDictionary();
    EXPECT_TRUE(topLevel.get());

    return topLevel->GetList("events");
  }

  static size_t GetEventListSize(CefRefPtr<CefValue> value) {
    CefRefPtr<CefListValue> events = GetEventList(value);
    if (events)
      return events->GetSize();
    return 0U;
  }

  static CefRefPtr<CefDictionaryValue> GetEventValue(CefRefPtr<CefValue> value,
                                                     size_t index) {
    CefRefPtr<CefListValue> events = GetEventList(value);
    if (!events)
      return nullptr;
    EXPECT_LT(index, events->GetSize());
    CefRefPtr<CefDictionaryValue> event = events->GetDictionary(index);
    EXPECT_TRUE(event);
    return event;
  }

  static void GetFirstUpdateAndEvent(CefRefPtr<CefValue> value,
                                     CefRefPtr<CefDictionaryValue>& update,
                                     CefRefPtr<CefDictionaryValue>& event) {
    if (GetUpdateListSize(value) > 0U)
      update = GetUpdateValue(value, 0U);
    if (GetEventListSize(value) > 0U)
      event = GetEventValue(value, 0U);
  }

  static bool GetFirstMatchingEvent(CefRefPtr<CefValue> value,
                                    const std::string& event_type,
                                    CefRefPtr<CefDictionaryValue>& event) {
    // Return the first event that matches the requested |event_type|.
    const size_t event_size = GetEventListSize(value);
    for (size_t i = 0; i < event_size; ++i) {
      CefRefPtr<CefDictionaryValue> cur_event = GetEventValue(value, i);
      const std::string& cur_event_type = cur_event->GetString("event_type");
      if (cur_event_type == event_type) {
        event = cur_event;
        return true;
      }
    }
    return false;
  }

  void TestEnableAccessibilityUpdate(CefRefPtr<CefValue> value) {
    CefRefPtr<CefDictionaryValue> update, event;
    GetFirstUpdateAndEvent(value, update, event);
    EXPECT_TRUE(update.get());

    // Ignore other events.
    if (!event.get() || event->GetString("event_type") != "layoutComplete") {
      return;
    }

    // Get update and validate it has tree data
    EXPECT_TRUE(update->GetBool("has_tree_data"));
    CefRefPtr<CefDictionaryValue> treeData = update->GetDictionary("tree_data");

    // Validate title and Url
    EXPECT_STREQ("AccessibilityTest",
                 treeData->GetString("title").ToString().c_str());
    EXPECT_STREQ(kTestUrl, treeData->GetString("url").ToString().c_str());

    // Validate node data
    CefRefPtr<CefListValue> nodes = update->GetList("nodes");
    EXPECT_TRUE(nodes.get());
    EXPECT_GT(nodes->GetSize(), 0U);

    // Update has a valid root
    CefRefPtr<CefDictionaryValue> root;
    for (size_t index = 0; index < nodes->GetSize(); index++) {
      CefRefPtr<CefDictionaryValue> node = nodes->GetDictionary(index);
      if (node->GetString("role").ToString() == "rootWebArea") {
        root = node;
        break;
      }
    }
    EXPECT_TRUE(root.get());

    // One div containing the tree elements.
    CefRefPtr<CefListValue> childIDs = root->GetList("child_ids");
    EXPECT_TRUE(childIDs.get());
    EXPECT_EQ(1U, childIDs->GetSize());

    // A parent Group div containing the child.
    CefRefPtr<CefDictionaryValue> group;
    for (size_t index = 0; index < nodes->GetSize(); index++) {
      CefRefPtr<CefDictionaryValue> node = nodes->GetDictionary(index);
      if (node->GetString("role").ToString() == "genericContainer") {
        group = node;
        break;
      }
    }
    EXPECT_TRUE(group.get());
    // Validate Group is child of root WebArea.
    EXPECT_EQ(group->GetInt("id"), childIDs->GetInt(0));

    CefRefPtr<CefListValue> parentdiv = group->GetList("child_ids");
    EXPECT_TRUE(parentdiv.get());
    EXPECT_EQ(3U, parentdiv->GetSize());

    int tipId = parentdiv->GetInt(0);
    int editBoxId = parentdiv->GetInt(1);
    int buttonId = parentdiv->GetInt(2);

    // A parent Group div containing the child.
    CefRefPtr<CefDictionaryValue> tip, editbox, button;
    for (size_t index = 0; index < nodes->GetSize(); index++) {
      CefRefPtr<CefDictionaryValue> node = nodes->GetDictionary(index);
      if (node->GetInt("id") == tipId) {
        tip = node;
      }
      if (node->GetInt("id") == editBoxId) {
        editbox = node;
      }
      if (node->GetInt("id") == buttonId) {
        button = node;
      }
    }
    EXPECT_TRUE(tip.get());
    EXPECT_STREQ("tooltip", tip->GetString("role").ToString().c_str());
    CefRefPtr<CefDictionaryValue> tipattr = tip->GetDictionary("attributes");
    EXPECT_TRUE(tipattr.get());

    EXPECT_TRUE(editbox.get());
    EXPECT_STREQ("textField", editbox->GetString("role").ToString().c_str());
    CefRefPtr<CefDictionaryValue> editattr =
        editbox->GetDictionary("attributes");
    // Validate ARIA Description tags for tipIdare associated with editbox.
    EXPECT_TRUE(editattr.get());
    EXPECT_EQ(tipId, editattr->GetList("describedbyIds")->GetInt(0));
    EXPECT_STREQ(kTipText,
                 editattr->GetString("description").ToString().c_str());

    EXPECT_TRUE(button.get());
    EXPECT_STREQ("button", button->GetString("role").ToString().c_str());

    // Now Post a delayed task to destroy the test
    // giving sufficient time for any accessibility updates to come through
    CefPostDelayedTask(
        TID_UI, base::Bind(&AccessibilityTestHandler::DestroyTest, this), 500);
  }

  // Find Edit box Id in accessibility tree.
  void SetEditBoxIdAndRect(CefRefPtr<CefDictionaryValue> value) {
    EXPECT_TRUE(value.get());
    // Validate node data.
    CefRefPtr<CefListValue> nodes = value->GetList("nodes");
    EXPECT_TRUE(nodes.get());
    EXPECT_GT(nodes->GetSize(), 0U);

    // Find accessibility id for the text field.
    for (size_t index = 0; index < nodes->GetSize(); index++) {
      CefRefPtr<CefDictionaryValue> node = nodes->GetDictionary(index);
      if (node->GetString("role").ToString() == "textField") {
        edit_box_id_ = node->GetInt("id");
        CefRefPtr<CefDictionaryValue> loc = node->GetDictionary("location");
        EXPECT_TRUE(loc.get());
        EXPECT_GT(loc->GetDouble("x"), 0);
        EXPECT_GT(loc->GetDouble("y"), 0);
        EXPECT_GT(loc->GetDouble("width"), 0);
        EXPECT_GT(loc->GetDouble("height"), 0);
        break;
      }
    }
  }

  void DestroyTest() override {
    if (test_type_ == TEST_LOCATION_CHANGE) {
      EXPECT_GT(edit_box_id_, 0);
      EXPECT_TRUE(got_hide_edit_box_);
      EXPECT_TRUE(got_accessibility_location_change_);
    }
    TestHandler::DestroyTest();
  }

  AccessibilityTestType test_type_;
  int edit_box_id_;
  bool accessibility_disabled_;
  TrackCallback got_hide_edit_box_;
  TrackCallback got_accessibility_location_change_;

  IMPLEMENT_REFCOUNTING(AccessibilityTestHandler);
};

}  // namespace

TEST(OSRTest, AccessibilityEnable) {
  CefRefPtr<AccessibilityTestHandler> handler =
      new AccessibilityTestHandler(TEST_ENABLE);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

TEST(OSRTest, AccessibilityDisable) {
  CefRefPtr<AccessibilityTestHandler> handler =
      new AccessibilityTestHandler(TEST_DISABLE);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

TEST(OSRTest, AccessibilityFocusChange) {
  CefRefPtr<AccessibilityTestHandler> handler =
      new AccessibilityTestHandler(TEST_FOCUS_CHANGE);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

TEST(OSRTest, AccessibilityLocationChange) {
  CefRefPtr<AccessibilityTestHandler> handler =
      new AccessibilityTestHandler(TEST_LOCATION_CHANGE);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}
