// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/vr/browser_renderer.h"

#include "base/memory/raw_ptr.h"
#include "chrome/browser/vr/graphics_delegate.h"
#include "chrome/browser/vr/input_delegate.h"
#include "chrome/browser/vr/input_event.h"
#include "chrome/browser/vr/model/controller_model.h"
#include "chrome/browser/vr/model/reticle_model.h"
#include "chrome/browser/vr/render_info.h"
#include "chrome/browser/vr/scheduler_delegate.h"
#include "chrome/browser/vr/test/mock_browser_ui_interface.h"
#include "chrome/browser/vr/ui_interface.h"
#include "testing/gmock/include/gmock/gmock.h"

using ::testing::_;
using ::testing::Return;

namespace vr {

class MockUi : public UiInterface {
 public:
  MockUi() = default;
  ~MockUi() override = default;

  base::WeakPtr<BrowserUiInterface> GetBrowserUiWeakPtr() override {
    return nullptr;
  }
  SchedulerUiInterface* GetSchedulerUiPtr() override { return nullptr; }
  MOCK_METHOD4(
      OnGlInitialized,
      void(GlTextureLocation, unsigned int, unsigned int, unsigned int));
  MOCK_METHOD4(SetAlertDialogEnabled,
               void(bool, PlatformUiInputDelegate*, float, float));
  MOCK_METHOD4(SetContentOverlayAlertDialogEnabled,
               void(bool, PlatformUiInputDelegate*, float, float));
  MOCK_METHOD0(OnPause, void());
  void OnControllersUpdated(const std::vector<ControllerModel>&,
                            const ReticleModel&) override {}
  void OnProjMatrixChanged(const gfx::Transform&) override {}
  MOCK_METHOD0(AcceptDoffPromptForTesting, void());
  MOCK_METHOD2(GetTargetPointForTesting,
               gfx::Point3F(UserFriendlyElementName,
                            const gfx::PointF& position));
  MOCK_METHOD1(GetElementVisibilityForTesting, bool(UserFriendlyElementName));
  MOCK_METHOD1(SetUiInputManagerForTesting, void(bool));
  MOCK_METHOD0(IsContentVisibleAndOpaque, bool());
  MOCK_METHOD1(SetContentUsesQuadLayer, void(bool));
  gfx::Transform GetContentWorldSpaceTransform() override { return {}; }
  MOCK_METHOD2(OnBeginFrame, bool(base::TimeTicks, const gfx::Transform&));
  MOCK_CONST_METHOD0(SceneHasDirtyTextures, bool());
  MOCK_METHOD0(UpdateSceneTextures, void());
  MOCK_METHOD1(Draw, void(const RenderInfo&));
  MOCK_METHOD3(DrawContent, void(const float (&)[16], float, float));
  MOCK_METHOD2(DrawWebXr, void(int, const float (&)[16]));
  MOCK_METHOD1(DrawWebVrOverlayForeground, void(const RenderInfo&));
  MOCK_METHOD0(HasWebXrOverlayElementsToDraw, bool());
  MOCK_METHOD5(HandleInput,
               void(base::TimeTicks,
                    const RenderInfo&,
                    const ControllerModel&,
                    ReticleModel*,
                    InputEventList*));
  MOCK_METHOD1(HandleMenuButtonEvents, void(InputEventList*));
  FovRectangles GetMinimalFovForWebXrOverlayElements(const gfx::Transform&,
                                                     const FovRectangle&,
                                                     const gfx::Transform&,
                                                     const FovRectangle&,
                                                     float) override {
    return {};
  }
};

class MockSchedulerDelegate : public SchedulerDelegate {
 public:
  MockSchedulerDelegate() = default;
  ~MockSchedulerDelegate() override = default;

  // SchedulerDelegate
  void OnPause() override {}
  void OnResume() override {}
  MOCK_METHOD0(OnExitPresent, void());
  MOCK_METHOD1(SetWebXrMode, void(bool));
  MOCK_METHOD1(SetShowingVrDialog, void(bool));
  void SetBrowserRenderer(SchedulerBrowserRendererInterface*) override {}
  MOCK_METHOD2(SubmitDrawnFrame, void(FrameType, const gfx::Transform&));
  void AddInputSourceState(
      device::mojom::XRInputSourceStatePtr state) override {}
  void ConnectPresentingService(
      device::mojom::XRRuntimeSessionOptionsPtr options) override {}
};

class MockGraphicsDelegate : public GraphicsDelegate {
 public:
  MockGraphicsDelegate() = default;
  ~MockGraphicsDelegate() override = default;

  bool using_buffer() { return using_buffer_; }

  // GraphicsDelegate
  void OnResume() {}
  FovRectangles GetRecommendedFovs() override { return {}; }
  float GetZNear() override { return 0; }
  RenderInfo GetRenderInfo(FrameType, const gfx::Transform&) override {
    return {};
  }
  RenderInfo GetOptimizedRenderInfoForFovs(const FovRectangles&) override {
    return {};
  }
  void InitializeBuffers() override {}
  void PrepareBufferForWebXr() override { UseBuffer(); }
  void PrepareBufferForWebXrOverlayElements() override { UseBuffer(); }
  void PrepareBufferForContentQuadLayer(const gfx::Transform&) override {
    UseBuffer();
  }
  void PrepareBufferForBrowserUi() override { UseBuffer(); }
  void OnFinishedDrawingBuffer() override {
    CHECK(using_buffer_);
    using_buffer_ = false;
  }
  void GetWebXrDrawParams(int*, Transform*) override {}
  bool IsContentQuadReady() override { return true; }
  MOCK_METHOD0(ResumeContentRendering, void());
  MOCK_METHOD2(BufferBoundsChanged, void(const gfx::Size&, const gfx::Size&));
  void GetContentQuadDrawParams(Transform*, float*, float*) override {}
  MOCK_METHOD0(GetContentBufferWidth, int());
  MOCK_METHOD1(SetTexturesInitializedCallback,
               void(TexturesInitializedCallback));
  bool Initialize(const scoped_refptr<gl::GLSurface>&) override { return true; }
  bool RunInSkiaContext(base::OnceClosure callback) override {
    std::move(callback).Run();
    return true;
  }
  void SetFrameDumpFilepathBase(std::string& filepath_base) override {}

 private:
  void UseBuffer() {
    CHECK(!using_buffer_);
    using_buffer_ = true;
  }
  bool using_buffer_ = false;
};

class MockInputDelegate : public InputDelegate {
 public:
  MockInputDelegate() = default;
  ~MockInputDelegate() override = default;

  // InputDelegate
  gfx::Transform GetHeadPose() override { return {}; }
  void OnTriggerEvent(bool pressed) override {}
  MOCK_METHOD3(UpdateController,
               void(const gfx::Transform&, base::TimeTicks, bool));
  MOCK_METHOD1(GetControllerModel, ControllerModel(const gfx::Transform&));
  MOCK_METHOD1(GetGestures, InputEventList(base::TimeTicks));
  device::mojom::XRInputSourceStatePtr GetInputSourceState() override {
    return nullptr;
  }
  void OnResume() override {}
  void OnPause() override {}
};

class BrowserRendererTest : public testing::Test {
 public:
  struct BuildParams {
    std::unique_ptr<MockUi> ui;
    std::unique_ptr<MockSchedulerDelegate> scheduler_delegate;
    std::unique_ptr<MockGraphicsDelegate> graphics_delegate;
    std::unique_ptr<MockInputDelegate> input_delegate;
  };

  void SetUp() override {
    auto ui = std::make_unique<MockUi>();
    build_params_ = {
        std::make_unique<MockUi>(), std::make_unique<MockSchedulerDelegate>(),
        std::make_unique<MockGraphicsDelegate>(),
        std::make_unique<MockInputDelegate>(),
    };
    ui_ = build_params_.ui.get();
    scheduler_delegate_ = build_params_.scheduler_delegate.get();
    graphics_delegate_ = build_params_.graphics_delegate.get();
    input_delegate_ = build_params_.input_delegate.get();
  }

  std::unique_ptr<SchedulerBrowserRendererInterface> CreateBrowserRenderer() {
    return std::make_unique<BrowserRenderer>(
        std::move(build_params_.ui),
        std::move(build_params_.scheduler_delegate),
        std::move(build_params_.graphics_delegate),
        std::move(build_params_.input_delegate), nullptr,
        1 /* sliding_time_size */);
  }

 protected:
  raw_ptr<MockUi> ui_;
  raw_ptr<MockSchedulerDelegate> scheduler_delegate_;
  raw_ptr<MockGraphicsDelegate> graphics_delegate_;
  raw_ptr<MockInputDelegate> input_delegate_;

 private:
  BuildParams build_params_;
};

TEST_F(BrowserRendererTest, DrawBrowserFrameUseContentQuadLayer) {
  testing::Sequence s;
  auto browser_renderer = CreateBrowserRenderer();
  EXPECT_CALL(*ui_, SetContentUsesQuadLayer(true))
      .After(EXPECT_CALL(*ui_, IsContentVisibleAndOpaque())
                 .WillOnce(Return(true)));
  EXPECT_CALL(*ui_, SceneHasDirtyTextures()).WillOnce(Return(false));
  EXPECT_CALL(*ui_, UpdateSceneTextures).Times(0);

  testing::Expectation update_controller =
      EXPECT_CALL(*input_delegate_, UpdateController(_, _, false)).Times(1);
  EXPECT_CALL(*ui_, OnBeginFrame(_, _)).Times(1).InSequence(s);
  EXPECT_CALL(*ui_, HandleInput(_, _, _, _, _))
      .Times(1)
      .InSequence(s)
      .After(EXPECT_CALL(*input_delegate_, GetGestures(_))
                 .Times(1)
                 .After(update_controller),
             EXPECT_CALL(*input_delegate_, GetControllerModel(_))
                 .Times(1)
                 .After(update_controller));
  EXPECT_CALL(*ui_, HandleMenuButtonEvents(_)).Times(0);

  EXPECT_CALL(*ui_, DrawContent(_, _, _)).Times(1).InSequence(s);
  EXPECT_CALL(*ui_, Draw(_)).Times(1).InSequence(s);
  EXPECT_CALL(*ui_, DrawWebXr(_, _)).Times(0);
  EXPECT_CALL(*ui_, DrawWebVrOverlayForeground(_)).Times(0);
  EXPECT_CALL(*scheduler_delegate_, SubmitDrawnFrame(kUiFrame, _))
      .Times(1)
      .InSequence(s);

  browser_renderer->DrawBrowserFrame(base::TimeTicks());
  EXPECT_FALSE(graphics_delegate_->using_buffer());
}

TEST_F(BrowserRendererTest, DrawBrowserFrameContentNoQuadLayer) {
  testing::Sequence s;
  auto browser_renderer = CreateBrowserRenderer();
  EXPECT_CALL(*ui_, SetContentUsesQuadLayer(false))
      .After(EXPECT_CALL(*ui_, IsContentVisibleAndOpaque())
                 .WillOnce(Return(false)));
  EXPECT_CALL(*ui_, SceneHasDirtyTextures()).WillOnce(Return(false));
  EXPECT_CALL(*ui_, UpdateSceneTextures).Times(0);

  testing::Expectation update_controller =
      EXPECT_CALL(*input_delegate_, UpdateController(_, _, false)).Times(1);
  EXPECT_CALL(*ui_, OnBeginFrame(_, _)).Times(1).InSequence(s);
  EXPECT_CALL(*ui_, HandleInput(_, _, _, _, _))
      .Times(1)
      .InSequence(s)
      .After(EXPECT_CALL(*input_delegate_, GetGestures(_))
                 .Times(1)
                 .After(update_controller),
             EXPECT_CALL(*input_delegate_, GetControllerModel(_))
                 .Times(1)
                 .After(update_controller));
  EXPECT_CALL(*ui_, HandleMenuButtonEvents(_)).Times(0);

  EXPECT_CALL(*ui_, DrawContent(_, _, _)).Times(0);
  EXPECT_CALL(*ui_, Draw(_)).Times(1).InSequence(s);
  EXPECT_CALL(*ui_, DrawWebXr(_, _)).Times(0);
  EXPECT_CALL(*ui_, DrawWebVrOverlayForeground(_)).Times(0);
  EXPECT_CALL(*scheduler_delegate_, SubmitDrawnFrame(kUiFrame, _))
      .Times(1)
      .InSequence(s);

  browser_renderer->DrawBrowserFrame(base::TimeTicks());
  EXPECT_FALSE(graphics_delegate_->using_buffer());
}

TEST_F(BrowserRendererTest, DrawBrowserFrameDirtyTextures) {
  testing::Sequence s;
  auto browser_renderer = CreateBrowserRenderer();
  EXPECT_CALL(*ui_, SetContentUsesQuadLayer(false))
      .After(EXPECT_CALL(*ui_, IsContentVisibleAndOpaque())
                 .WillOnce(Return(false)));
  EXPECT_CALL(*ui_, SceneHasDirtyTextures()).WillOnce(Return(true));

  testing::Expectation update_controller =
      EXPECT_CALL(*input_delegate_, UpdateController(_, _, false)).Times(1);
  EXPECT_CALL(*ui_, OnBeginFrame(_, _)).Times(1).InSequence(s);
  EXPECT_CALL(*ui_, HandleInput(_, _, _, _, _))
      .Times(1)
      .InSequence(s)
      .After(EXPECT_CALL(*input_delegate_, GetGestures(_))
                 .Times(1)
                 .After(update_controller),
             EXPECT_CALL(*input_delegate_, GetControllerModel(_))
                 .Times(1)
                 .After(update_controller));

  EXPECT_CALL(*ui_, UpdateSceneTextures).Times(1).InSequence(s);

  EXPECT_CALL(*ui_, Draw(_)).Times(1).InSequence(s);
  EXPECT_CALL(*scheduler_delegate_, SubmitDrawnFrame(kUiFrame, _))
      .Times(1)
      .InSequence(s);

  browser_renderer->DrawBrowserFrame(base::TimeTicks());
  EXPECT_FALSE(graphics_delegate_->using_buffer());
}

TEST_F(BrowserRendererTest, DrawWebXrFrameNoOverlay) {
  testing::Sequence s;
  auto browser_renderer = CreateBrowserRenderer();
  EXPECT_CALL(*ui_, SetContentUsesQuadLayer(false))
      .After(EXPECT_CALL(*ui_, IsContentVisibleAndOpaque())
                 .WillOnce(Return(false)));
  EXPECT_CALL(*ui_, SceneHasDirtyTextures()).WillOnce(Return(false));
  EXPECT_CALL(*ui_, UpdateSceneTextures).Times(0);
  EXPECT_CALL(*ui_, HasWebXrOverlayElementsToDraw()).WillOnce(Return(false));

  // No input processing.
  testing::Expectation update_controller =
      EXPECT_CALL(*input_delegate_, UpdateController(_, _, _)).Times(0);
  EXPECT_CALL(*input_delegate_, GetGestures(_)).Times(0);
  EXPECT_CALL(*input_delegate_, GetControllerModel(_)).Times(0);
  EXPECT_CALL(*ui_, HandleInput(_, _, _, _, _)).Times(0);
  EXPECT_CALL(*ui_, HandleMenuButtonEvents(_)).Times(0);

  EXPECT_CALL(*ui_, OnBeginFrame(_, _)).Times(1).InSequence(s);
  EXPECT_CALL(*ui_, Draw(_)).Times(0);
  EXPECT_CALL(*ui_, DrawContent(_, _, _)).Times(0);
  EXPECT_CALL(*ui_, DrawWebXr(_, _)).Times(1).InSequence(s);
  EXPECT_CALL(*ui_, DrawWebVrOverlayForeground(_)).Times(0);
  EXPECT_CALL(*scheduler_delegate_, SubmitDrawnFrame(kWebXrFrame, _))
      .Times(1)
      .InSequence(s);

  browser_renderer->DrawWebXrFrame(base::TimeTicks(), {});
  EXPECT_FALSE(graphics_delegate_->using_buffer());
}

TEST_F(BrowserRendererTest, DrawWebXrFrameWithOverlay) {
  testing::Sequence s;
  auto browser_renderer = CreateBrowserRenderer();
  EXPECT_CALL(*ui_, SetContentUsesQuadLayer(false))
      .After(EXPECT_CALL(*ui_, IsContentVisibleAndOpaque())
                 .WillOnce(Return(false)));
  EXPECT_CALL(*ui_, SceneHasDirtyTextures()).WillOnce(Return(false));
  EXPECT_CALL(*ui_, UpdateSceneTextures).Times(0);
  EXPECT_CALL(*ui_, HasWebXrOverlayElementsToDraw()).WillOnce(Return(true));

  // No input processing.
  testing::Expectation update_controller =
      EXPECT_CALL(*input_delegate_, UpdateController(_, _, _)).Times(0);
  EXPECT_CALL(*input_delegate_, GetGestures(_)).Times(0);
  EXPECT_CALL(*input_delegate_, GetControllerModel(_)).Times(0);
  EXPECT_CALL(*ui_, HandleInput(_, _, _, _, _)).Times(0);
  EXPECT_CALL(*ui_, HandleMenuButtonEvents(_)).Times(0);

  EXPECT_CALL(*ui_, OnBeginFrame(_, _)).Times(1).InSequence(s);
  EXPECT_CALL(*ui_, Draw(_)).Times(0);
  EXPECT_CALL(*ui_, DrawContent(_, _, _)).Times(0);
  EXPECT_CALL(*ui_, DrawWebXr(_, _)).Times(1).InSequence(s);
  EXPECT_CALL(*ui_, DrawWebVrOverlayForeground(_)).Times(1).InSequence(s);
  EXPECT_CALL(*scheduler_delegate_, SubmitDrawnFrame(kWebXrFrame, _))
      .Times(1)
      .InSequence(s);

  browser_renderer->DrawWebXrFrame(base::TimeTicks(), {});
  EXPECT_FALSE(graphics_delegate_->using_buffer());
}

TEST_F(BrowserRendererTest, ProcessControllerInputForWebXr) {
  testing::Sequence s;
  auto browser_renderer = CreateBrowserRenderer();

  testing::Expectation update_controller =
      EXPECT_CALL(*input_delegate_, UpdateController(_, _, true))
          .Times(1)
          .InSequence(s);
  EXPECT_CALL(*input_delegate_, GetGestures(_)).Times(1).InSequence(s);
  EXPECT_CALL(*input_delegate_, GetControllerModel(_)).Times(0);
  EXPECT_CALL(*ui_, HandleInput(_, _, _, _, _)).Times(0);
  EXPECT_CALL(*ui_, HandleMenuButtonEvents(_)).Times(1).InSequence(s);

  browser_renderer->ProcessControllerInputForWebXr(gfx::Transform(),
                                                   base::TimeTicks());
}

}  // namespace vr
