// Copyright 2015 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 "remoting/test/app_remoting_latency_test_fixture.h"

#include <utility>

#include "base/bind.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "remoting/proto/event.pb.h"
#include "remoting/protocol/input_stub.h"
#include "remoting/test/app_remoting_connection_helper.h"
#include "remoting/test/app_remoting_test_driver_environment.h"
#include "remoting/test/rgb_value.h"
#include "remoting/test/test_chromoting_client.h"
#include "remoting/test/test_video_renderer.h"

namespace remoting {
namespace test {

AppRemotingLatencyTestFixture::AppRemotingLatencyTestFixture() {
  // NOTE: Derived fixture must initialize application details in constructor.
}

AppRemotingLatencyTestFixture::~AppRemotingLatencyTestFixture() = default;

void AppRemotingLatencyTestFixture::SetUp() {
  std::unique_ptr<TestVideoRenderer> test_video_renderer(
      new TestVideoRenderer());
  test_video_renderer_ = test_video_renderer->GetWeakPtr();

  std::unique_ptr<TestChromotingClient> test_chromoting_client(
      new TestChromotingClient(std::move(test_video_renderer)));

  test_chromoting_client->AddRemoteConnectionObserver(this);

  connection_helper_.reset(
      new AppRemotingConnectionHelper(GetApplicationDetails()));
  connection_helper_->Initialize(std::move(test_chromoting_client));

  if (!connection_helper_->StartConnection()) {
    LOG(ERROR) << "Remote host connection could not be established.";
    FAIL();
  }

  if (!PrepareApplicationForTesting()) {
    LOG(ERROR) << "Unable to prepare application for testing.";
    FAIL();
  }
}

void AppRemotingLatencyTestFixture::TearDown() {
  // Only reset application state when remote host connection is established.
  if (connection_helper_->ConnectionIsReadyForTest()) {
    ResetApplicationState();
  }

  connection_helper_->test_chromoting_client()->RemoveRemoteConnectionObserver(
      this);
  connection_helper_.reset();
}

WaitForImagePatternMatchCallback
AppRemotingLatencyTestFixture::SetExpectedImagePattern(
    const webrtc::DesktopRect& expected_rect,
    const RGBValue& expected_color) {
  std::unique_ptr<base::RunLoop> run_loop(new base::RunLoop());

  test_video_renderer_->ExpectAverageColorInRect(expected_rect, expected_color,
                                                 run_loop->QuitClosure());

  return base::Bind(&AppRemotingLatencyTestFixture::WaitForImagePatternMatch,
                    base::Unretained(this), base::Passed(&run_loop));
}

void AppRemotingLatencyTestFixture::SaveFrameDataToDisk(
    bool save_frame_data_to_disk) {
  test_video_renderer_->SaveFrameDataToDisk(save_frame_data_to_disk);
}

bool AppRemotingLatencyTestFixture::WaitForImagePatternMatch(
    std::unique_ptr<base::RunLoop> run_loop,
    const base::TimeDelta& max_wait_time) {
  DCHECK(run_loop);
  DCHECK(!timer_.IsRunning());

  timer_.Start(FROM_HERE, max_wait_time, run_loop->QuitClosure());

  run_loop->Run();

  // Image pattern is matched if we stopped because of the reply not the timer.
  bool image_pattern_is_matched = (timer_.IsRunning());
  timer_.Stop();
  run_loop.reset();

  return image_pattern_is_matched;
}

void AppRemotingLatencyTestFixture::HostMessageReceived(
    const protocol::ExtensionMessage& message) {
  if (!host_message_received_callback_.is_null()) {
    host_message_received_callback_.Run(message);
  }
}

void AppRemotingLatencyTestFixture::PressKey(ui::DomCode dom_code,
                                             bool pressed) {
  remoting::protocol::KeyEvent event;
  event.set_usb_keycode(static_cast<unsigned int>(dom_code));
  event.set_pressed(pressed);
  connection_helper_->input_stub()->InjectKeyEvent(event);
}

void AppRemotingLatencyTestFixture::PressAndReleaseKey(ui::DomCode dom_code) {
  PressKey(dom_code, true);
  PressKey(dom_code, false);
}

void AppRemotingLatencyTestFixture::PressAndReleaseKeyCombination(
    const std::vector<ui::DomCode>& dom_codes) {
  for (auto iter = dom_codes.begin(); iter != dom_codes.end(); ++iter) {
    PressKey(*iter, true);
  }
  for (auto iter = dom_codes.rbegin(); iter != dom_codes.rend(); ++iter) {
    PressKey(*iter, false);
  }
}

void AppRemotingLatencyTestFixture::SetHostMessageReceivedCallback(
    const HostMessageReceivedCallback& host_message_received_callback) {
  host_message_received_callback_ = host_message_received_callback;
}

void AppRemotingLatencyTestFixture::ResetHostMessageReceivedCallback() {
  host_message_received_callback_.Reset();
}

void AppRemotingLatencyTestFixture::ResetApplicationState() {
  DCHECK(!timer_.IsRunning());
  DCHECK(!run_loop_ || !run_loop_->running());

  // Give the app some time to settle before reseting to initial state.
  run_loop_.reset(new base::RunLoop());
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop_->QuitClosure(), base::TimeDelta::FromSeconds(1));
  run_loop_->Run();

  // Press Alt + F4 and wait for amount of time for the input to be delivered
  // and processed.
  std::vector<ui::DomCode> dom_codes;
  dom_codes.push_back(ui::DomCode::ALT_LEFT);
  dom_codes.push_back(ui::DomCode::F4);
  PressAndReleaseKeyCombination(dom_codes);

  run_loop_.reset(new base::RunLoop());
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop_->QuitClosure(), base::TimeDelta::FromSeconds(2));
  run_loop_->Run();

  // Press 'N' to choose not save and wait for 1 second for the input to be
  // delivered and processed.
  PressAndReleaseKey(ui::DomCode::US_N);

  run_loop_.reset(new base::RunLoop());
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop_->QuitClosure(), base::TimeDelta::FromSeconds(2));
  run_loop_->Run();
  run_loop_.reset();
}

}  // namespace test
}  // namespace remoting
