// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <string>
#include <vector>

#include "base/base_paths.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "cobalt/accessibility/screen_reader.h"
#include "cobalt/accessibility/text_alternative.h"
#include "cobalt/accessibility/tts_engine.h"
#include "cobalt/browser/web_module.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/window.h"
#include "cobalt/test/document_loader.h"
#include "starboard/window.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;

namespace cobalt {
namespace accessibility {
namespace {
struct TestInfo {
  TestInfo(const std::string& html_file_name,
           const std::string& expected_result,
           bool screen_reader_enabled)
      : html_file_name(html_file_name),
        expected_result(expected_result),
        screen_reader_enabled(screen_reader_enabled) {}
  std::string html_file_name;
  std::string expected_result;
  bool screen_reader_enabled;
};

// Enumerate the *.html files in the accessibility_test directory and build
// a list of input .html files and expected results.
std::vector<TestInfo> EnumerateTests(bool screen_reader_enabled,
                                     const std::string& subdir) {
  std::vector<TestInfo> infos;
  FilePath root_directory;
  PathService::Get(base::DIR_TEST_DATA, &root_directory);
  root_directory = root_directory.Append("cobalt")
                       .Append("accessibility")
                       .Append("testdata")
                       .Append(subdir);
  file_util::FileEnumerator enumerator(root_directory, false,
                                       file_util::FileEnumerator::FILES);
  for (FilePath html_file = enumerator.Next(); !html_file.empty();
       html_file = enumerator.Next()) {
    if (html_file.Extension() == ".html") {
      FilePath expected_results_file = html_file.ReplaceExtension(".expected");
      std::string results;
      if (!file_util::ReadFileToString(expected_results_file, &results)) {
        DLOG(WARNING) << "Failed to read results from file: "
                      << expected_results_file.value();
        continue;
      }
      TrimWhitespaceASCII(results, TRIM_ALL, &results);
      infos.push_back(TestInfo(html_file.BaseName().value(),
                               results,
                               screen_reader_enabled));
    }
  }
  return infos;
}

class MockTTSEngine : public TTSEngine {
 public:
  MOCK_METHOD1(Speak, void(const std::string&));
  MOCK_METHOD1(SpeakNow, void(const std::string&));
};

class TextAlternativeTest : public ::testing::TestWithParam<TestInfo> {
 protected:
  test::DocumentLoader document_loader_;
};

class LiveRegionMutationTest : public ::testing::TestWithParam<TestInfo> {
 public:
  LiveRegionMutationTest() : quit_event_(true, false) {}
  void OnError(const GURL&, const std::string& error) {
    DLOG(ERROR) << error;
    Quit();
  }
  void Quit() {
    quit_event_.Signal();
    screen_reader_.reset();
  }
  void OnClose(base::TimeDelta close_time) {
    UNREFERENCED_PARAMETER(close_time);
    Quit();
  }

  scoped_refptr<script::Wrappable> CreateWindowAttribute(
      const scoped_refptr<dom::Window>& window,
      dom::MutationObserverTaskManager* mutation_observer_task_manager,
      script::GlobalEnvironment* global_environment) {
    UNREFERENCED_PARAMETER(global_environment);
    screen_reader_.reset(new accessibility::ScreenReader(
        window->document(), &tts_engine_, mutation_observer_task_manager));
    screen_reader_->set_enabled(GetParam().screen_reader_enabled);
    EXPECT_EQ(GetParam().screen_reader_enabled, screen_reader_->enabled());

    return NULL;
  }

  static void OnRenderTreeProducedStub(
      const browser::WebModule::LayoutResults&) {}

 protected:
  MockTTSEngine tts_engine_;
  base::WaitableEvent quit_event_;
  scoped_ptr<accessibility::ScreenReader> screen_reader_;
};
}  // namespace

TEST_P(TextAlternativeTest, TextAlternativeTest) {
  GURL url(
      std::string("file:///cobalt/accessibility/testdata/text_alternative/" +
                  GetParam().html_file_name));
  document_loader_.Load(url);
  ASSERT_TRUE(document_loader_.document());
  scoped_refptr<dom::Element> element =
      document_loader_.document()->GetElementById("element_to_test");
  ASSERT_TRUE(element);
  EXPECT_EQ(GetParam().expected_result, ComputeTextAlternative(element));
}

// This test broke  because LiveRegionMutationTest::CreateWindowAttribute()
// returns a NULL script::Wrappable, which the javascript engine will attempt
// to dereference.
TEST_P(LiveRegionMutationTest, DISABLED_LiveRegionMutationTest) {
  GURL url(std::string("file:///cobalt/accessibility/testdata/live_region/" +
                       GetParam().html_file_name));
  const math::Size kDefaultViewportSize(1280, 720);
  const float kDefaultVideoPixelRatio = 1.0f;
  const float kRefreshRate = 60.0f;

  network::NetworkModule network_module((network::NetworkModule::Options()));
  render_tree::ResourceProviderStub resource_provider;

  // Use test runner mode to allow the content itself to dictate when it is
  // ready for layout should be performed.  See cobalt/dom/test_runner.h.
  browser::WebModule::Options web_module_options;
  web_module_options.injected_window_attributes["test"] = base::Bind(
      &LiveRegionMutationTest::CreateWindowAttribute, base::Unretained(this));

  // Set expected result from mutation.
  std::string expected_speech = GetParam().expected_result;
  if (expected_speech.empty() || !GetParam().screen_reader_enabled) {
    EXPECT_CALL(tts_engine_, Speak(_)).Times(0);
  } else {
    EXPECT_CALL(tts_engine_, Speak(expected_speech));
  }

  // Create the webmodule and let it run.
  DLOG(INFO) << url.spec();
  browser::WebModule web_module(
      url, base::kApplicationStateStarted,
      base::Bind(&LiveRegionMutationTest::OnRenderTreeProducedStub),
      base::Bind(&LiveRegionMutationTest::OnError, base::Unretained(this)),
      base::Bind(&LiveRegionMutationTest::OnClose, base::Unretained(this)),
      base::Closure(), /* window_minimize_callback */
      NULL /* can_play_type_handler */, NULL /* web_media_player_factory */,
      &network_module, kDefaultViewportSize, kDefaultVideoPixelRatio,
      &resource_provider, kRefreshRate, web_module_options);

  // Wait for the test to quit.
  quit_event_.Wait();
}

INSTANTIATE_TEST_CASE_P(
    TextAlternativeTest, TextAlternativeTest,
    ::testing::ValuesIn(EnumerateTests(true, "text_alternative")));

INSTANTIATE_TEST_CASE_P(
    LiveRegionMutationTestEnabled, LiveRegionMutationTest,
    ::testing::ValuesIn(EnumerateTests(true, "live_region")));

INSTANTIATE_TEST_CASE_P(
    LiveRegionMutationTestDisabled, LiveRegionMutationTest,
    ::testing::ValuesIn(EnumerateTests(false, "live_region")));
}  // namespace accessibility
}  // namespace cobalt
