// Copyright 2015 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 <memory>

#include "cobalt/loader/loader.h"

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "cobalt/dom/url_utils.h"
#include "cobalt/loader/file_fetcher.h"
#include "cobalt/loader/text_decoder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::_;

namespace cobalt {
namespace loader {
namespace {

//////////////////////////////////////////////////////////////////////////
// Callbacks
//////////////////////////////////////////////////////////////////////////

class TextDecoderCallback {
 public:
  explicit TextDecoderCallback(base::RunLoop* run_loop) : run_loop_(run_loop) {}

  void OnDone(const Origin&, std::unique_ptr<std::string> text) {
    text_ = *text;
    base::MessageLoop::current()->task_runner()->PostTask(
        FROM_HERE, run_loop_->QuitClosure());
  }

  std::string text() { return text_; }

 private:
  base::RunLoop* run_loop_;
  std::string text_;
};

class LoaderCallback {
 public:
  LoaderCallback() : run_loop_(NULL) {}
  explicit LoaderCallback(base::RunLoop* run_loop) : run_loop_(run_loop) {}

  void OnLoadComplete(const base::Optional<std::string>& text) {
    if (!text) return;

    DLOG(ERROR) << *text;
    if (run_loop_)
      base::MessageLoop::current()->task_runner()->PostTask(
          FROM_HERE, run_loop_->QuitClosure());
  }

 private:
  base::RunLoop* run_loop_;
};

//////////////////////////////////////////////////////////////////////////
// Mocks & Stubs
//////////////////////////////////////////////////////////////////////////

class MockDecoder : public Decoder {
 public:
  static std::unique_ptr<Decoder> Create(
      MockDecoder* mock_decoder,
      const loader::Loader::OnCompleteFunction& load_complete_callback =
          loader::Loader::OnCompleteFunction()) {
    SB_UNREFERENCED_PARAMETER(load_complete_callback);
    return std::unique_ptr<Decoder>(mock_decoder);
  }

  MOCK_METHOD2(DecodeChunk, void(const char*, size_t));
  MOCK_METHOD0(Finish, void());
  MOCK_METHOD0(Suspend, bool());
  MOCK_METHOD1(Resume, void(render_tree::ResourceProvider*));
};

class MockFetcher : public Fetcher {
 public:
  explicit MockFetcher(Handler* handler) : Fetcher(handler) {}

  void FireError(const char* message) { handler()->OnError(this, message); }

  void FireReceived(const char* data, size_t size) {
    handler()->OnReceived(this, data, size);
  }

  void FireDone() { handler()->OnDone(this); }

  static std::unique_ptr<Fetcher> Create(Handler* handler) {
    return std::unique_ptr<Fetcher>(new MockFetcher(handler));
  }
};

struct MockFetcherFactory {
 public:
  MockFetcherFactory() : count(0) {}
  // Way to access the last fetcher created by the fetcher factory.
  MockFetcher* fetcher;
  int count;

  std::unique_ptr<Fetcher> Create(Fetcher::Handler* handler) {
    fetcher = new MockFetcher(handler);
    ++count;
    return std::unique_ptr<Fetcher>(fetcher);
  }

  Loader::FetcherCreator GetFetcherCreator() {
    return base::Bind(&MockFetcherFactory::Create, base::Unretained(this));
  }
};

class MockLoaderCallback : public LoaderCallback {
 public:
  MockLoaderCallback() {
    ON_CALL(*this, OnLoadComplete(_))
        .WillByDefault(Invoke(&real_, &LoaderCallback::OnLoadComplete));
  }

  MOCK_METHOD1(OnLoadComplete, void(const base::Optional<std::string>&));

 private:
  LoaderCallback real_;
};

}  // namespace

//////////////////////////////////////////////////////////////////////////
// LoaderTest
//////////////////////////////////////////////////////////////////////////

class LoaderTest : public ::testing::Test {
 protected:
  LoaderTest();
  ~LoaderTest() override {}

  base::FilePath data_dir_;
  base::MessageLoop message_loop_;
};

LoaderTest::LoaderTest() : message_loop_(base::MessageLoop::TYPE_DEFAULT) {
  data_dir_ = data_dir_.Append(FILE_PATH_LITERAL("cobalt"))
                  .Append(FILE_PATH_LITERAL("loader"))
                  .Append(FILE_PATH_LITERAL("testdata"));
}

TEST_F(LoaderTest, FetcherError) {
  MockLoaderCallback mock_loader_callback;
  MockFetcherFactory mock_fetcher_factory;
  MockDecoder* mock_decoder = new MockDecoder();  // To be owned by loader.
  EXPECT_CALL(*mock_decoder, DecodeChunk(_, _)).Times(0);
  EXPECT_CALL(*mock_decoder, Finish()).Times(0);
  EXPECT_CALL(mock_loader_callback, OnLoadComplete(_));

  Loader loader(mock_fetcher_factory.GetFetcherCreator(),
                base::Bind(&MockDecoder::Create, mock_decoder),
                base::Bind(&MockLoaderCallback::OnLoadComplete,
                           base::Unretained(&mock_loader_callback)));
  mock_fetcher_factory.fetcher->FireError("Fail");
}

TEST_F(LoaderTest, FetcherSuspendAbort) {
  MockLoaderCallback mock_loader_callback;
  MockFetcherFactory mock_fetcher_factory;
  MockDecoder* mock_decoder = new MockDecoder();  // To be owned by loader.
  EXPECT_CALL(*mock_decoder, DecodeChunk(_, _)).Times(0);
  EXPECT_CALL(*mock_decoder, Finish()).Times(0);
  EXPECT_CALL(*mock_decoder, Suspend());
  EXPECT_CALL(*mock_decoder, Resume(_)).Times(0);
  EXPECT_CALL(mock_loader_callback, OnLoadComplete(_));

  Loader loader(mock_fetcher_factory.GetFetcherCreator(),
                base::Bind(&MockDecoder::Create, mock_decoder),
                base::Bind(&MockLoaderCallback::OnLoadComplete,
                           base::Unretained(&mock_loader_callback)));
  loader.Suspend();
}

TEST_F(LoaderTest, FetcherSuspendResumeDone) {
  MockLoaderCallback mock_loader_callback;
  MockFetcherFactory mock_fetcher_factory;
  MockDecoder* mock_decoder = new MockDecoder();  // To be owned by loader.
  ON_CALL(*mock_decoder, Suspend()).WillByDefault(testing::Return(true));

  EXPECT_CALL(*mock_decoder, Suspend());
  EXPECT_CALL(*mock_decoder, Resume(_));

  EXPECT_CALL(*mock_decoder, DecodeChunk(_, _)).Times(0);
  EXPECT_CALL(mock_loader_callback, OnLoadComplete(_)).Times(0);
  EXPECT_CALL(*mock_decoder, Finish());

  Loader loader(mock_fetcher_factory.GetFetcherCreator(),
                base::Bind(&MockDecoder::Create, mock_decoder),
                base::Bind(&MockLoaderCallback::OnLoadComplete,
                           base::Unretained(&mock_loader_callback)));
  loader.Suspend();
  loader.Resume(NULL);

  // The fetcher should have been torn down and recreated.
  EXPECT_EQ(2, mock_fetcher_factory.count);
  mock_fetcher_factory.fetcher->FireDone();
}

TEST_F(LoaderTest, FetcherReceiveDone) {
  InSequence dummy;

  MockLoaderCallback mock_loader_callback;
  MockFetcherFactory mock_fetcher_factory;
  MockDecoder* mock_decoder = new MockDecoder();  // To be owned by loader.
  EXPECT_CALL(mock_loader_callback, OnLoadComplete(_)).Times(0);
  EXPECT_CALL(*mock_decoder, DecodeChunk(_, _));
  EXPECT_CALL(*mock_decoder, Finish());

  Loader loader(mock_fetcher_factory.GetFetcherCreator(),
                base::Bind(&MockDecoder::Create, mock_decoder),
                base::Bind(&MockLoaderCallback::OnLoadComplete,
                           base::Unretained(&mock_loader_callback)));
  mock_fetcher_factory.fetcher->FireReceived(NULL, 0);
  mock_fetcher_factory.fetcher->FireDone();
}

// Typical usage of Loader.
TEST_F(LoaderTest, ValidFileEndToEndTest) {
  // Create a RunLoop that helps us use the base::MessageLoop, which is in the
  // test fixture object.
  base::RunLoop run_loop;

  // Create a loader, using a FileFetcher that loads from disk, and a
  // TextDecoder that sees the received bytes as plain text.
  const base::FilePath file_path = data_dir_.Append("performance-spike.html");
  FileFetcher::Options fetcher_options;
  TextDecoderCallback text_decoder_callback(&run_loop);
  LoaderCallback loader_callback(&run_loop);
  Loader loader(
      base::Bind(&FileFetcher::Create, file_path, fetcher_options),
      base::Bind(&loader::TextDecoder::Create,
                 base::Bind(&TextDecoderCallback::OnDone,
                            base::Unretained(&text_decoder_callback))),
      base::Bind(&LoaderCallback::OnLoadComplete,
                 base::Unretained(&loader_callback)));

  // When the message loop runs, the loader will start loading. It'll quit when
  // loading is finished.
  run_loop.Run();

  // Get the loaded result from the decoder callback.
  std::string loaded_text = text_decoder_callback.text();

  // Compare the result with that of other API's.
  std::string expected_text;
  base::FilePath dir_test_data;
  EXPECT_TRUE(base::PathService::Get(base::DIR_TEST_DATA, &dir_test_data));
  EXPECT_TRUE(
      base::ReadFileToString(dir_test_data.Append(file_path), &expected_text));
  EXPECT_EQ(expected_text, loaded_text);
}

}  // namespace loader
}  // namespace cobalt
