/*
 * Copyright 2010 Google Inc.
 *
 * 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.
 */

// Author: sligocki@google.com (Shawn Ligocki)

#include "net/instaweb/http/public/mock_url_fetcher.h"

#include "net/instaweb/http/public/async_fetch.h"
#include "net/instaweb/http/public/request_context.h"
#include "net/instaweb/http/public/url_async_fetcher.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/google_message_handler.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/base/time_util.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/request_headers.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/kernel/util/platform.h"

namespace net_instaweb {

namespace {

// Class for encapsulating objects needed to execute fetches.
class MockFetchContainer {
 public:
  MockFetchContainer(UrlAsyncFetcher* fetcher, ThreadSystem* thread_system)
      : fetcher_(fetcher),
        fetch_(RequestContext::NewTestRequestContext(thread_system),
               &response_body_),
        thread_system_(thread_system) {
    fetch_.set_request_headers(&request_headers_);
    fetch_.set_response_headers(&response_headers_);
  }

  bool Fetch(const GoogleString& url) {
    fetcher_->Fetch(url, &handler_, &fetch_);
    EXPECT_TRUE(fetch_.done());
    return fetch_.success();
  }

  UrlAsyncFetcher* fetcher_;
  GoogleString response_body_;
  RequestHeaders request_headers_;
  ResponseHeaders response_headers_;
  StringAsyncFetch fetch_;
  GoogleMessageHandler handler_;
  ThreadSystem* thread_system_;

 private:
  DISALLOW_COPY_AND_ASSIGN(MockFetchContainer);
};

class MockUrlFetcherTest : public ::testing::Test {
 protected:
  MockUrlFetcherTest() : thread_system_(Platform::CreateThreadSystem()) {
    fetcher_.set_fail_on_unexpected(false);
  }

  void TestResponse(const GoogleString& url,
                    const ResponseHeaders& expected_header,
                    const GoogleString& expected_body) {
    MockFetchContainer fetch(&fetcher_, thread_system_.get());
    EXPECT_TRUE(fetch.Fetch(url));
    EXPECT_EQ(expected_header.ToString(), fetch.response_headers_.ToString());
    EXPECT_EQ(expected_body, fetch.response_body_);
  }

  void TestFetchFail(const GoogleString& url) {
    MockFetchContainer fetch(&fetcher_, thread_system_.get());
    EXPECT_FALSE(fetch.Fetch(url));
  }

  MockUrlFetcher fetcher_;
  scoped_ptr<ThreadSystem> thread_system_;
};

TEST_F(MockUrlFetcherTest, GetsCorrectMappedResponse) {
  const char url1[] = "http://www.example.com/successs.html";
  ResponseHeaders header1;
  header1.set_first_line(1, 1, 200, "OK");
  const char body1[] = "This website loaded :)";

  const char url2[] = "http://www.example.com/failure.html";
  ResponseHeaders header2;
  header2.set_first_line(1, 1, 404, "Not Found");
  const char body2[] = "File Not Found :(";

  // We can't fetch the URLs before they're set.
  // Note: this does not crash because we are using NullMessageHandler.
  TestFetchFail(url1);
  TestFetchFail(url2);

  // Set the responses.
  fetcher_.SetResponse(url1, header1, body1);
  fetcher_.SetResponse(url2, header2, body2);

  // Now we can fetch the correct URLs
  TestResponse(url1, header1, body1);
  TestResponse(url2, header2, body2);

  // Check that we can fetch the same URL multiple times.
  TestResponse(url1, header1, body1);


  // Check that fetches fail after disabling the fetcher_.
  fetcher_.Disable();
  TestFetchFail(url1);
  // And then work again when re-enabled.
  fetcher_.Enable();
  TestResponse(url1, header1, body1);


  // Change the response. Test both editability and memory management.
  fetcher_.SetResponse(url1, header2, body2);

  // Check that we get the new response.
  TestResponse(url1, header2, body2);

  // Change it back.
  fetcher_.SetResponse(url1, header1, body1);
  TestResponse(url1, header1, body1);
}

TEST_F(MockUrlFetcherTest, ConditionalFetchTest) {
  const char url[] = "http://www.example.com/successs.html";
  ResponseHeaders header;
  header.set_first_line(1, 1, 200, "OK");
  // TODO(sligocki): Perhaps set Last-Modified header...
  const char body[] = "This website loaded :)";

  int64 old_time = 1000;
  int64 last_modified_time = 2000;
  int64 new_time = 3000;
  GoogleString old_time_string, now_string, new_time_string;
  ASSERT_TRUE(ConvertTimeToString(old_time, &old_time_string));
  ASSERT_TRUE(ConvertTimeToString(last_modified_time, &now_string));
  ASSERT_TRUE(ConvertTimeToString(new_time, &new_time_string));

  fetcher_.SetConditionalResponse(url, last_modified_time, "", header, body);

  // Response is normal to an un-conditional GET.
  TestResponse(url, header, body);

  // Also normal for conditional GET with old time.
  {
    MockFetchContainer fetch(&fetcher_, thread_system_.get());
    fetch.request_headers_.Add(HttpAttributes::kIfModifiedSince,
                               old_time_string);
    EXPECT_TRUE(fetch.Fetch(url));
    EXPECT_EQ(header.ToString(), fetch.response_headers_.ToString());
    EXPECT_EQ(body, fetch.response_body_);
  }

  // But conditional GET with current time gets 304 Not Modified response.
  {
    MockFetchContainer fetch(&fetcher_, thread_system_.get());
    fetch.request_headers_.Add(HttpAttributes::kIfModifiedSince,
                               now_string);
    EXPECT_TRUE(fetch.Fetch(url));
    EXPECT_EQ(HttpStatus::kNotModified, fetch.response_headers_.status_code());
  }

  // Future time also gets 304 Not Modified.
  {
    MockFetchContainer fetch(&fetcher_, thread_system_.get());
    fetch.request_headers_.Add(HttpAttributes::kIfModifiedSince,
                               new_time_string);
    EXPECT_TRUE(fetch.Fetch(url));
    EXPECT_EQ(HttpStatus::kNotModified, fetch.response_headers_.status_code());
  }
}

TEST_F(MockUrlFetcherTest, ConditionalFetchWithEtagsTest) {
  const char url[] = "http://www.example.com/successs.html";
  const char etag[] = "etag";
  ResponseHeaders header;
  header.set_first_line(1, 1, 200, "OK");
  const char body[] = "This website loaded :)";

  fetcher_.SetConditionalResponse(url, -1, etag, header, body);

  // Response is normal to an un-conditional GET.
  TestResponse(url, header, body);

  // Also normal for conditional GET with wrong etag.
  {
    MockFetchContainer fetch(&fetcher_, thread_system_.get());
    fetch.request_headers_.Add(HttpAttributes::kIfNoneMatch, "blah");
    EXPECT_TRUE(fetch.Fetch(url));
    EXPECT_EQ(header.ToString(), fetch.response_headers_.ToString());
    EXPECT_EQ(body, fetch.response_body_);
  }

  // But conditional GET with correct etag gets 304 Not Modified response.
  {
    MockFetchContainer fetch(&fetcher_, thread_system_.get());
    fetch.request_headers_.Add(HttpAttributes::kIfNoneMatch, etag);
    EXPECT_TRUE(fetch.Fetch(url));
    EXPECT_EQ(HttpStatus::kNotModified, fetch.response_headers_.status_code());
  }
}

TEST_F(MockUrlFetcherTest, UpdateHeaderDates) {
  MockTimer timer(thread_system_->NewMutex(), MockTimer::kApr_5_2010_ms);
  fetcher_.set_timer(&timer);
  fetcher_.set_update_date_headers(true);

  const char url[] = "http://www.example.com/foo.css";
  const char body[] = "resource body";
  ResponseHeaders header;
  header.set_first_line(1, 1, 200, "OK");
  header.SetLastModified(MockTimer::kApr_5_2010_ms - 2 * Timer::kDayMs);
  const int64 ttl_ms = 5 * Timer::kMinuteMs;
  header.SetDateAndCaching(timer.NowMs(), ttl_ms);

  fetcher_.SetResponse(url, header, body);

  // Fetch it at current time.
  {
    MockFetchContainer fetch(&fetcher_, thread_system_.get());
    EXPECT_TRUE(fetch.Fetch(url));
    // Check that response header's expiration time is set correctly.
    EXPECT_EQ(timer.NowMs() + ttl_ms,
              fetch.response_headers_.CacheExpirationTimeMs());
  }

  // Fetch it at current time.
  timer.AdvanceMs(1 * Timer::kYearMs);  // Arbitrary time > 5min (max-age).
  {
    MockFetchContainer fetch(&fetcher_, thread_system_.get());
    EXPECT_TRUE(fetch.Fetch(url));
    // Check that response header's expiration time is set correctly.
    EXPECT_EQ(timer.NowMs() + ttl_ms,
              fetch.response_headers_.CacheExpirationTimeMs());
  }
}

TEST_F(MockUrlFetcherTest, FailAfterBody) {
  const char kUrl[] = "http://www.example.com/foo.css";
  ResponseHeaders response_headers;
  response_headers.SetStatusAndReason(HttpStatus::kOK);
  RequestHeaders request_headres;
  fetcher_.SetResponse(kUrl, response_headers, "hello");
  fetcher_.SetResponseFailure(kUrl);
  MockFetchContainer fetch(&fetcher_, thread_system_.get());
  EXPECT_FALSE(fetch.Fetch(kUrl));
  EXPECT_EQ("hello", fetch.response_body_);
}

TEST_F(MockUrlFetcherTest, ErrorMessage) {
  const char kError[] = "404 Sad Robot";
  fetcher_.set_fail_on_unexpected(false);
  fetcher_.set_error_message(kError);
  RequestHeaders request_headres;
  MockFetchContainer fetch(&fetcher_, thread_system_.get());
  EXPECT_FALSE(fetch.Fetch("http://example.com/404"));
  EXPECT_EQ(kError, fetch.response_body_);
}

}  // namespace

}  // namespace net_instaweb
