// Copyright 2017 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 "topaz/runtime/web_view/web_view_impl.h"

#include <hid/hid.h>
#include <hid/usages.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/fdio/io.h>
#include <zircon/pixelformat.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include "topaz/runtime/web_view/schema_org_context.h"

using namespace WebCore;

TouchTracker::TouchTracker(int x, int y)
    : start_x_(x), start_y_(y), last_x_(0), last_y_(0), is_drag_(false) {}

void TouchTracker::HandleEvent(const fuchsia::ui::input::PointerEvent& pointer,
                               const fuchsia::ui::gfx::Metrics& metrics,
                               WebView& web_view) {
  const auto x = pointer.x * metrics.scale_x;
  const auto y = pointer.y * metrics.scale_y;
  const int kDragThreshhold = 50 * metrics.scale_x;
  auto delta_x = last_x_ - x;
  auto delta_y = last_y_ - y;
  auto distance_x = abs(start_x_ - x);
  auto distance_y = abs(start_y_ - y);
  last_y_ = y;
  last_x_ = x;

  if (distance_x > kDragThreshhold || distance_y > kDragThreshhold) {
    is_drag_ = true;
  }

  if (is_drag_) {
    switch (pointer.phase) {
      case fuchsia::ui::input::PointerEventPhase::MOVE:
        web_view.scrollPixels(delta_x, delta_y);
        break;

      case fuchsia::ui::input::PointerEventPhase::UP:
        web_view.scrollPixels(delta_x, delta_y);
        break;

      default:
        break;
    }
  } else {
    switch (pointer.phase) {
      case fuchsia::ui::input::PointerEventPhase::UP:
        web_view.handleMouseEvent(start_x_, start_y_, WebView::kMouseDown);
        web_view.handleMouseEvent(start_x_, start_y_, WebView::kMouseUp);
        break;

      default:
        break;
    }
  }
}

WebViewImpl::WebViewImpl(scenic::ViewContext view_context,
                         fuchsia::ui::input::ImeServicePtr ime_service,
                         const std::string& url)
    : V1BaseView(std::move(view_context), "WebView"),
      ime_service_(std::move(ime_service)),
      ime_client_binding_(this),
      weak_factory_(this),
      url_(url),
#ifdef EXPERIMENTAL_WEB_ENTITY_EXTRACTION
      schema_org_(web_view_),
#endif
      image_cycler_(session()) {
  FXL_LOG(INFO) << "WebViewImpl constructor";
  web_view_.setup_once();

  std::function<void(bool)> focusDelegate = [=](bool focused) {
    this->HandleWebRequestsFocusEvent(focused);
  };

  web_view_.setInputFocusDelegate(focusDelegate);

  SetNeedSquareMetrics(true);
  parent_node().AddChild(image_cycler_);

  // Expose |WebView| interface to caller.
  outgoing_services().AddService<fuchsia::webview::WebView>(
      [this](fidl::InterfaceRequest<fuchsia::webview::WebView> request) {
        FXL_LOG(INFO) << "web view service request";
        web_view_interface_bindings_.AddBinding(this, std::move(request));
      });

  async::PostTask(async_get_default_dispatcher(),
                  ([weak = weak_factory_.GetWeakPtr()]() {
                    if (weak)
                      weak->CallIdle();
                  }));
}

void WebViewImpl::HandleWebRequestsFocusEvent(bool focused) {
  FXL_LOG(INFO) << "WebView: web requests input focus:"
                << (focused ? "focused" : "unfocused");
  web_requests_input_ = focused;
  UpdateInputConnection();
}

void WebViewImpl::UpdateInputConnection() {
  if (web_requests_input_) {
    ime_service_->ShowKeyboard();

    fuchsia::ui::input::InputMethodEditorClientPtr client_ptr;
    ime_client_binding_.Bind(client_ptr.NewRequest());
    auto state = fuchsia::ui::input::TextInputState{};
    state.text = "";
    ime_service_->GetInputMethodEditor(
        fuchsia::ui::input::KeyboardType::TEXT,
        fuchsia::ui::input::InputMethodAction::SEND, std::move(state),
        std::move(client_ptr), ime_.NewRequest());
  } else if (ime_client_binding_.is_bound()) {
    ime_service_->HideKeyboard();
    ime_client_binding_.Unbind();
  }
}

// |fuchsia::ui::input::InputMethodEditorClient|
void WebViewImpl::DidUpdateState(fuchsia::ui::input::TextInputState state,
                                 fuchsia::ui::input::InputEventPtr event) {
  if (event != nullptr && event->is_keyboard() && has_scenic_focus_) {
    HandleKeyboardEvent(*event);
  }
}

// |fuchsia::ui::input::InputMethodEditorClient|
void WebViewImpl::OnAction(fuchsia::ui::input::InputMethodAction action) {
  if (fuchsia::ui::input::InputMethodAction::SEND == action) {
    // treat send action as return, simulate press and release.
    fuchsia::ui::input::InputEvent event;
    fuchsia::ui::input::KeyboardEvent keyboard;
    keyboard.phase = fuchsia::ui::input::KeyboardEventPhase::PRESSED;
    keyboard.hid_usage = HID_USAGE_KEY_ENTER;
    event.set_keyboard(keyboard);
    HandleKeyboardEvent(event);

    keyboard.phase = fuchsia::ui::input::KeyboardEventPhase::RELEASED;
    HandleKeyboardEvent(event);
  }
}

// |WebView|:
void WebViewImpl::SetUrl(fidl::StringPtr url) {
  url_ = url;
  // Reset url_set_ so that the next OnDraw() knows to call
  // web_view_.setURL()
  url_set_ = false;
  InvalidateScene();
}

// |WebView|:
void WebViewImpl::ClearCookies() { web_view_.deleteAllCookies(); }

void WebViewImpl::SetWebRequestDelegate(
    ::fidl::InterfaceHandle<fuchsia::webview::WebRequestDelegate> delegate) {
  webRequestDelegate_ = delegate.Bind();
}

bool WebViewImpl::HandleKeyboardEvent(
    const fuchsia::ui::input::InputEvent& event) {
  bool handled = true;
  const fuchsia::ui::input::KeyboardEvent& keyboard = event.keyboard();
  bool pressed =
      keyboard.phase == fuchsia::ui::input::KeyboardEventPhase::PRESSED;
  bool repeating =
      keyboard.phase == fuchsia::ui::input::KeyboardEventPhase::REPEAT;
  if (pressed && keyboard.code_point == 'c' &&
      keyboard.modifiers & fuchsia::ui::input::kModifierControl) {
    exit(0);
  } else if (pressed && keyboard.code_point == '[' &&
             keyboard.modifiers & fuchsia::ui::input::kModifierControl) {
    web_view_.goBack();
  } else if (pressed && keyboard.code_point == ']' &&
             keyboard.modifiers & fuchsia::ui::input::kModifierControl) {
    web_view_.goForward();
  } else if (pressed && keyboard.code_point == 'r' &&
             keyboard.modifiers & fuchsia::ui::input::kModifierControl) {
    web_view_.reload();
  } else {
    bool handled =
        web_view_.handleKeyEvent(keyboard.hid_usage, keyboard.code_point,
                                 pressed || repeating, repeating);
    if (!handled) {
      if (pressed || repeating) {
        if (keyboard.hid_usage == HID_USAGE_KEY_DOWN) {
        } else if (keyboard.hid_usage == HID_USAGE_KEY_UP) {
          web_view_.scrollUpOneLine();
        } else if (keyboard.hid_usage == HID_USAGE_KEY_RIGHT) {
          web_view_.scrollRightOneLine();
        } else if (keyboard.hid_usage == HID_USAGE_KEY_LEFT) {
          web_view_.scrollLeftOneLine();
        }
      }
    }
  }
  return handled;
}

void WebViewImpl::HandleMouseEvent(
    const fuchsia::ui::input::PointerEvent& pointer) {
  if (pointer.buttons & fuchsia::ui::input::kMousePrimaryButton) {
    switch (pointer.phase) {
      case fuchsia::ui::input::PointerEventPhase::DOWN:
      case fuchsia::ui::input::PointerEventPhase::MOVE:
        web_view_.handleMouseEvent(
            pointer.x * metrics().scale_x, pointer.y * metrics().scale_y,
            pointer.phase == fuchsia::ui::input::PointerEventPhase::DOWN
                ? ::WebView::kMouseDown
                : ::WebView::kMouseMoved);
        break;
      case fuchsia::ui::input::PointerEventPhase::UP:
        web_view_.handleMouseEvent(pointer.x * metrics().scale_x,
                                   pointer.y * metrics().scale_y,
                                   ::WebView::kMouseUp);
        break;
      default:
        break;
    }
  }
}

void WebViewImpl::HandleTouchDown(
    const fuchsia::ui::input::PointerEvent& pointer) {
  const auto x = pointer.x * metrics().scale_x;
  const auto y = pointer.y * metrics().scale_y;
  touch_trackers_[pointer.pointer_id] = TouchTracker(x, y);
}

void WebViewImpl::HandleTouchEvent(
    const fuchsia::ui::input::PointerEvent& pointer) {
  auto pointer_id = pointer.pointer_id;
  switch (pointer.phase) {
    case fuchsia::ui::input::PointerEventPhase::DOWN:
      HandleTouchDown(pointer);
      break;
    case fuchsia::ui::input::PointerEventPhase::MOVE:
      touch_trackers_[pointer_id].HandleEvent(pointer, metrics(), web_view_);
      break;
    case fuchsia::ui::input::PointerEventPhase::UP:
      touch_trackers_[pointer_id].HandleEvent(pointer, metrics(), web_view_);
      touch_trackers_.erase(pointer_id);
      break;
    default:
      break;
  }
}

void WebViewImpl::HandleFocusEvent(
    const fuchsia::ui::input::FocusEvent& focus) {
  has_scenic_focus_ = focus.focused;
  web_view_.setFocused(focus.focused);
  UpdateInputConnection();
}

// |scenic::V1BaseView|
bool WebViewImpl::OnInputEvent(fuchsia::ui::input::InputEvent event) {
  bool handled = false;
  web_view_.setVisible(true);
  if (event.is_pointer()) {
    handled = true;
    const fuchsia::ui::input::PointerEvent& pointer = event.pointer();
    if (pointer.type == fuchsia::ui::input::PointerEventType::TOUCH) {
      HandleTouchEvent(pointer);
    } else if (pointer.type == fuchsia::ui::input::PointerEventType::MOUSE) {
      HandleMouseEvent(pointer);
    }
  } else if (event.is_keyboard()) {
    handled = true;
    HandleKeyboardEvent(event);
  } else if (event.is_focus()) {
    handled = true;
    HandleFocusEvent(event.focus());
  }

  InvalidateScene();
  return handled;
}

// |scenic::V1BaseView|
void WebViewImpl::OnSceneInvalidated(
    fuchsia::images::PresentationInfo presentation_info) {
  if (!has_physical_size())
    return;

  // Update the image.
  const scenic::HostImage* image = image_cycler_.AcquireImage(
      physical_size().width, physical_size().height, physical_size().width * 4u,
      fuchsia::images::PixelFormat::BGRA_8, fuchsia::images::ColorSpace::SRGB);
  FXL_DCHECK(image);

  // Paint the webview.
  web_view_.setup(reinterpret_cast<unsigned char*>(image->image_ptr()),
                  ZX_PIXEL_FORMAT_ARGB_8888, physical_size().width,
                  physical_size().height, physical_size().width * 4u);
  if (!url_set_) {
    const char* urlToOpen = url_.c_str();
    web_view_.setURL(urlToOpen);
    url_set_ = true;

    FXL_DCHECK(metrics().scale_x ==
               metrics().scale_y);  // we asked for square metrics

    auto requestCallback = [this](std::string url) {
      if (webRequestDelegate_) {
        webRequestDelegate_->WillSendRequest(url);
      }
      return url;
    };
    web_view_.setWebRequestDelegate(requestCallback);
  }

  if (page_scale_factor_ != metrics().scale_x) {
    page_scale_factor_ = metrics().scale_x;
    web_view_.setPageAndTextZoomFactors(page_scale_factor_, 1.0);
  }

  web_view_.iterateEventLoop();
  web_view_.layoutAndPaint();

  image_cycler_.ReleaseAndSwapImage();
  image_cycler_.SetScale(1.f / metrics().scale_x, 1.f / metrics().scale_y, 1.f);
  image_cycler_.SetTranslation(logical_size().width * .5f,
                               logical_size().height * .5f, 0.f);
}

void WebViewImpl::CallIdle() {
  web_view_.iterateEventLoop();
  InvalidateScene();
  async::PostTask(async_get_default_dispatcher(),
                  ([weak = weak_factory_.GetWeakPtr()]() {
                    if (weak)
                      weak->CallIdle();
                  }));
}
