// Copyright (c) 2012 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 "ppapi/tests/test_fullscreen.h"

#include <stdio.h>
#include <string.h>
#include <string>

#include "ppapi/c/ppb_fullscreen.h"
#include "ppapi/cpp/image_data.h"
#include "ppapi/cpp/input_event.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/point.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

REGISTER_TEST_CASE(Fullscreen);

namespace {

const ColorPremul kSheerBlue = { 0x88, 0x00, 0x00, 0x88 };
const ColorPremul kOpaqueYellow = { 0xFF, 0xFF, 0xFF, 0x00 };
const int kBytesPerPixel = sizeof(uint32_t);  // 4 bytes for BGRA or RGBA.

uint32_t FormatColor(PP_ImageDataFormat format, ColorPremul color) {
  if (format == PP_IMAGEDATAFORMAT_BGRA_PREMUL)
    return (color.A << 24) | (color.R << 16) | (color.G << 8) | (color.B);
  else if (format == PP_IMAGEDATAFORMAT_RGBA_PREMUL)
    return (color.A << 24) | (color.B << 16) | (color.G << 8) | (color.R);
  else
    return 0;
}

bool HasMidScreen(const pp::Rect& position, const pp::Size& screen_size) {
  static int32_t mid_x = screen_size.width() / 2;
  static int32_t mid_y = screen_size.height() / 2;
  return (position.Contains(mid_x, mid_y));
}

void FlushCallbackCheckImageData(void* data, int32_t result) {
  static_cast<TestFullscreen*>(data)->CheckPluginPaint();
}

}  // namespace

TestFullscreen::TestFullscreen(TestingInstance* instance)
    : TestCase(instance),
      error_(),
      screen_mode_(instance),
      painted_color_(0),
      fullscreen_pending_(false),
      normal_pending_(false),
      fullscreen_event_(instance->pp_instance()),
      normal_event_(instance->pp_instance()) {
  screen_mode_.GetScreenSize(&screen_size_);
}

bool TestFullscreen::Init() {
  if (screen_size_.IsEmpty()) {
    instance_->AppendError("Failed to initialize screen_size_");
    return false;
  }
  graphics2d_ = pp::Graphics2D(instance_, screen_size_, true);
  if (!instance_->BindGraphics(graphics2d_)) {
    instance_->AppendError("Failed to initialize graphics2d_");
    return false;
  }
  return CheckTestingInterface();
}

void TestFullscreen::RunTests(const std::string& filter) {
  RUN_TEST(GetScreenSize, filter);
  RUN_TEST(NormalToFullscreenToNormal, filter);
}

bool TestFullscreen::GotError() {
  return !error_.empty();
}

std::string TestFullscreen::Error() {
  std::string last_error = error_;
  error_.clear();
  return last_error;
}

// TODO(polina): consider adding custom logic to JS for this test to
// get screen.width and screen.height and postMessage those to this code,
// so the dimensions can be checked exactly.
std::string TestFullscreen::TestGetScreenSize() {
  if (screen_size_.width() < 320 || screen_size_.width() > 2560)
    return ReportError("screen_size.width()", screen_size_.width());
  if (screen_size_.height() < 200 || screen_size_.height() > 2048)
    return ReportError("screen_size.height()", screen_size_.height());
  PASS();
}

std::string TestFullscreen::TestNormalToFullscreenToNormal() {
  // 0. Start in normal mode.
  if (screen_mode_.IsFullscreen())
    return ReportError("IsFullscreen() at start", true);

  // 1. Switch to fullscreen.
  // This is only allowed within a context of a user gesture (e.g. mouse click).
  if (screen_mode_.SetFullscreen(true))
    return ReportError("SetFullscreen(true) outside of user gesture", true);
  // Trigger another call to SetFullscreen(true) from HandleInputEvent().
  // The transition is asynchronous and ends at the next DidChangeView().
  instance_->RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
  SimulateUserGesture();
  // DidChangeView() will call the callback once in fullscreen mode.
  fullscreen_event_.Wait();
  if (GotError())
    return Error();
  if (fullscreen_pending_)
    return "fullscreen_pending_ has not been reset";
  if (!screen_mode_.IsFullscreen())
    return ReportError("IsFullscreen() in fullscreen", false);

  // 2. Stay in fullscreen. No change.
  if (screen_mode_.SetFullscreen(true))
    return ReportError("SetFullscreen(true) in fullscreen", true);
  if (!screen_mode_.IsFullscreen())
    return ReportError("IsFullscreen() in fullscreen^2", false);

  // 3. Switch to normal.
  // The transition is asynchronous and ends at DidChangeView().
  // No graphics devices can be bound while in transition.
  normal_pending_ = true;
  if (!screen_mode_.SetFullscreen(false))
    return ReportError("SetFullscreen(false) in fullscreen", false);
  // DidChangeView() will signal once out of fullscreen mode.
  normal_event_.Wait();
  if (GotError())
    return Error();
  if (normal_pending_)
    return "normal_pending_ has not been reset";
  if (screen_mode_.IsFullscreen())
    return ReportError("IsFullscreen() in normal", true);

  // 4. Stay in normal. No change.
  if (screen_mode_.SetFullscreen(false))
    return ReportError("SetFullscreen(false) in normal", true);
  if (screen_mode_.IsFullscreen())
    return ReportError("IsFullscreen() in normal^2", true);

  PASS();
}

void TestFullscreen::SimulateUserGesture() {
  pp::Point plugin_center(
      normal_position_.x() + normal_position_.width() / 2,
      normal_position_.y() + normal_position_.height() / 2);
  pp::Point mouse_movement;
  pp::MouseInputEvent input_event(
      instance_,
      PP_INPUTEVENT_TYPE_MOUSEDOWN,
      0,  // time_stamp
      0,  // modifiers
      PP_INPUTEVENT_MOUSEBUTTON_LEFT,
      plugin_center,
      1,  // click_count
      mouse_movement);

  testing_interface_->SimulateInputEvent(instance_->pp_instance(),
                                         input_event.pp_resource());
}

void TestFullscreen::FailFullscreenTest(const std::string& error) {
  error_ = error;
  fullscreen_event_.Signal();
}

void TestFullscreen::FailNormalTest(const std::string& error) {
  error_ = error;
  normal_event_.Signal();
}

void TestFullscreen::PassFullscreenTest() {
  fullscreen_event_.Signal();
}

void TestFullscreen::PassNormalTest() {
  normal_event_.Signal();
}

// Transition to fullscreen can only happen when processing a user gesture.
bool TestFullscreen::HandleInputEvent(const pp::InputEvent& event) {
  // We only let mouse events through and only mouse clicks count.
  if (event.GetType() != PP_INPUTEVENT_TYPE_MOUSEDOWN &&
      event.GetType() != PP_INPUTEVENT_TYPE_MOUSEUP)
    return false;
  // We got the gesture. No need to handle any more events.
  instance_->ClearInputEventRequest(PP_INPUTEVENT_CLASS_MOUSE);
  if (screen_mode_.IsFullscreen()) {
    FailFullscreenTest(
        ReportError("IsFullscreen() before fullscreen transition", true));
    return false;
  }
  fullscreen_pending_ = true;
  if (!screen_mode_.SetFullscreen(true)) {
    FailFullscreenTest(ReportError("SetFullscreen(true) in normal", false));
    return false;
  }
  // DidChangeView() will complete the transition to fullscreen.
  return false;
}

bool TestFullscreen::PaintPlugin(pp::Size size, ColorPremul color) {
  painted_size_ = size;
  PP_ImageDataFormat image_format = pp::ImageData::GetNativeImageDataFormat();
  painted_color_ = FormatColor(image_format, color);
  if (painted_color_ == 0)
    return false;
  pp::Point origin(0, 0);

  pp::ImageData image(instance_, image_format, size, false);
  if (image.is_null())
    return false;
  uint32_t* pixels = static_cast<uint32_t*>(image.data());
  int num_pixels = image.stride() / kBytesPerPixel * image.size().height();
  for (int i = 0; i < num_pixels; i++)
    pixels[i] = painted_color_;
  graphics2d_.PaintImageData(image, origin);
  pp::CompletionCallback cc(FlushCallbackCheckImageData, this);
  if (graphics2d_.Flush(cc) != PP_OK_COMPLETIONPENDING)
    return false;

  return true;
}

void TestFullscreen::CheckPluginPaint() {
  PP_ImageDataFormat image_format = pp::ImageData::GetNativeImageDataFormat();
  pp::ImageData readback(instance_, image_format, painted_size_, false);
  pp::Point origin(0, 0);
  if (readback.is_null() ||
      PP_TRUE != testing_interface_->ReadImageData(graphics2d_.pp_resource(),
                                                   readback.pp_resource(),
                                                   &origin.pp_point())) {
    error_ = "Can't read plugin image";
    return;
  }
  for (int y = 0; y < painted_size_.height(); y++) {
    for (int x = 0; x < painted_size_.width(); x++) {
      uint32_t* readback_color = readback.GetAddr32(pp::Point(x, y));
      if (painted_color_ != *readback_color) {
        error_ = "Plugin image contains incorrect pixel value";
        return;
      }
    }
  }
  if (screen_mode_.IsFullscreen())
    PassFullscreenTest();
  else
    PassNormalTest();
}

// Transitions to/from fullscreen is asynchronous ending at DidChangeView.
// The number of calls to DidChangeView during fullscreen / normal transitions
// isn't specified by the API. The test waits until it the screen has
// transitioned to the desired state.
//
// WebKit does not change the plugin size, but Pepper does explicitly set
// it to screen width and height when SetFullscreen(true) is called and
// resets it back when ViewChanged is received indicating that we exited
// fullscreen.
//
// NOTE: The number of DidChangeView calls for <object> might be different.
// TODO(bbudge) Figure out how to test that the plugin positon eventually
// changes to normal_position_.
void TestFullscreen::DidChangeView(const pp::View& view) {
  pp::Rect position = view.GetRect();
  pp::Rect clip = view.GetClipRect();

  if (normal_position_.IsEmpty())
    normal_position_ = position;

  bool is_fullscreen = screen_mode_.IsFullscreen();
  if (fullscreen_pending_ && is_fullscreen) {
    fullscreen_pending_ = false;
    if (!HasMidScreen(position, screen_size_))
      FailFullscreenTest("DidChangeView is not in the middle of the screen");
    else if (position.size() != screen_size_)
      FailFullscreenTest("DidChangeView does not have screen size");
    // NOTE: we cannot reliably test for clip size being equal to the screen
    // because it might be affected by JS console, info bars, etc.
    else if (!instance_->BindGraphics(graphics2d_))
      FailFullscreenTest("Failed to BindGraphics() in fullscreen");
    else if (!PaintPlugin(position.size(), kOpaqueYellow))
      FailFullscreenTest("Failed to paint plugin image in fullscreen");
  } else if (normal_pending_ && !is_fullscreen) {
    normal_pending_ = false;
    if (screen_mode_.IsFullscreen())
      FailNormalTest("DidChangeview is in fullscreen");
    else if (!instance_->BindGraphics(graphics2d_))
      FailNormalTest("Failed to BindGraphics() in normal");
    else if (!PaintPlugin(position.size(), kSheerBlue))
      FailNormalTest("Failed to paint plugin image in normal");
  }
}
