// Copyright (c) 2014 The Chromium Embedded Framework 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 <algorithm>
#include <cstdlib>
#include <string>

#include "include/base/cef_bind.h"
#include "include/cef_stream.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "tests/ceftests/routing_test_handler.h"
#include "tests/gtest/include/gtest/gtest.h"

namespace {

const char kTestUrl[] = "http://tests-srh/test.html";
const size_t kReadBlockSize = 1024U;  // 1k.

// The usual network buffer size is about 32k. Choose a value that's larger.
const size_t kReadDesiredSize = 100U * 1024U;  // 100k

class ReadHandler : public CefReadHandler {
 public:
  explicit ReadHandler(bool may_block)
      : may_block_(may_block), offset_(0), expected_result_(0) {}

  void CreateContent() {
    // To verify that the data transers successfully we're going to make a big
    // math problem.
    content_.reserve(kReadDesiredSize + 50U);
    content_ = "<html><body><script>var myratherlongvariablename=0;";

    while (content_.size() < kReadDesiredSize) {
      content_ += "myratherlongvariablename=myratherlongvariablename+1;";
      expected_result_++;
    }

    content_ +=
        "window.testQuery({request:myratherlongvariablename+''});"
        "</script></body></html>";
  }

  int GetExpectedResult() const { return expected_result_; }

  size_t Read(void* ptr, size_t size, size_t n) override {
    EXPECT_EQ(1U, size);

    // Read the minimum of requested size, remaining size or kReadBlockSize.
    const size_t read_bytes =
        std::min(std::min(size * n, content_.size() - offset_), kReadBlockSize);
    if (read_bytes > 0) {
      memcpy(ptr, content_.c_str() + offset_, read_bytes);
      offset_ += read_bytes;
    }

    return read_bytes;
  }

  int Seek(int64 offset, int whence) override {
    EXPECT_TRUE(false);  // Not reached.
    return 0;
  }

  int64 Tell() override {
    EXPECT_TRUE(false);  // Not reached.
    return 0;
  }

  int Eof() override {
    EXPECT_TRUE(false);  // Not reached.
    return 0;
  }

  bool MayBlock() override { return may_block_; }

 private:
  const bool may_block_;
  std::string content_;
  size_t offset_;
  int expected_result_;

  IMPLEMENT_REFCOUNTING(ReadHandler);
};

class ReadTestHandler : public RoutingTestHandler {
 public:
  explicit ReadTestHandler(bool may_block)
      : may_block_(may_block), expected_result_(0) {}

  void RunTest() override {
    // Create the browser.
    CreateBrowser(kTestUrl);

    // Time out the test after a reasonable period of time.
    SetTestTimeout();
  }

  CefRefPtr<CefResourceHandler> GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) override {
    got_resource_handler_.yes();

    const std::string& url = request->GetURL();
    EXPECT_STREQ(kTestUrl, url.c_str());

    CefRefPtr<ReadHandler> handler = new ReadHandler(may_block_);
    handler->CreateContent();
    expected_result_ = handler->GetExpectedResult();

    CefRefPtr<CefStreamReader> stream =
        CefStreamReader::CreateForHandler(handler.get());
    return new CefStreamResourceHandler("text/html", stream);
  }

  bool OnQuery(CefRefPtr<CefBrowser> browser,
               CefRefPtr<CefFrame> frame,
               int64 query_id,
               const CefString& request,
               bool persistent,
               CefRefPtr<Callback> callback) override {
    got_on_query_.yes();

    const int actual_result = atoi(request.ToString().c_str());
    EXPECT_EQ(expected_result_, actual_result);

    DestroyTestIfDone();

    return true;
  }

  void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading,
                            bool canGoBack,
                            bool canGoForward) override {
    if (!isLoading) {
      got_on_loading_state_change_done_.yes();
      DestroyTestIfDone();
    }
  }

 private:
  void DestroyTestIfDone() {
    if (got_on_query_ && got_on_loading_state_change_done_)
      DestroyTest();
  }

  void DestroyTest() override {
    EXPECT_TRUE(got_resource_handler_);
    EXPECT_TRUE(got_on_query_);
    EXPECT_TRUE(got_on_loading_state_change_done_);
    RoutingTestHandler::DestroyTest();
  }

  const bool may_block_;

  int expected_result_;
  TrackCallback got_resource_handler_;
  TrackCallback got_on_query_;
  TrackCallback got_on_loading_state_change_done_;

  IMPLEMENT_REFCOUNTING(ReadTestHandler);
};

}  // namespace

TEST(StreamResourceHandlerTest, ReadWillBlock) {
  CefRefPtr<ReadTestHandler> handler = new ReadTestHandler(true);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

TEST(StreamResourceHandlerTest, ReadWontBlock) {
  CefRefPtr<ReadTestHandler> handler = new ReadTestHandler(false);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}
