/*
 * Copyright 2013 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: morlovich@google.com (Maksim Orlovich)

#include "net/instaweb/rewriter/public/google_font_service_input_resource.h"

#include "net/instaweb/http/public/counting_url_async_fetcher.h"
#include "net/instaweb/http/public/ua_sensitive_test_fetcher.h"
#include "net/instaweb/rewriter/public/mock_resource_callback.h"
#include "net/instaweb/rewriter/public/resource.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_test_base.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/ref_counted_ptr.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/http/content_type.h"
#include "pagespeed/kernel/http/google_url.h"
#include "pagespeed/kernel/http/response_headers.h"

namespace net_instaweb {

namespace {

const char kRoboto[] = "http://fonts.googleapis.com/css?family=Roboto";
const char kRobotoSsl[] = "https://fonts.googleapis.com/css?family=Roboto";
const char kNonCss[] = "http://fonts.googleapis.com/some.txt";

class GoogleFontServiceInputResourceTest : public RewriteTestBase {
 protected:
  virtual void SetUp() {
    RewriteTestBase::SetUp();
    GoogleFontServiceInputResource::InitStats(statistics());

    // Font loader CSS gets Cache-Control:private, max-age=86400
    ResponseHeaders response_headers;
    SetDefaultLongCacheHeaders(&kContentTypeCss, &response_headers);
    response_headers.SetDateAndCaching(
        timer()->NowMs(), 86400 * Timer::kSecondMs, ", private");

    // Set them up in spots where UaSensitiveFetcher would direct them.
    SetFetchResponse(StrCat(kRoboto, "&UA=Chromezilla"),
                     response_headers, "font_chromezilla");

    SetFetchResponse(StrCat(kRoboto, "&UA=Safieri"),
                     response_headers, "font_safieri");

    SetFetchResponse(StrCat(kRobotoSsl, "&UA=Chromezilla"),
                     response_headers, "sfont_chromezilla");

    SetFetchResponse(StrCat(kRobotoSsl, "&UA=Safieri"),
                     response_headers, "sfont_safieri");

    ResponseHeaders non_css;
    SetDefaultLongCacheHeaders(&kContentTypeText, &non_css);
    SetFetchResponse(StrCat(kNonCss, "?UA=Chromezilla"),
                     non_css, "something weird");
  }

  void ResetUserAgent(StringPiece user_agent) {
    ClearRewriteDriver();
    rewrite_driver()->SetSessionFetcher(
        new UserAgentSensitiveTestFetcher(rewrite_driver()->async_fetcher()));
    SetCurrentUserAgent(user_agent);
    SetDriverRequestHeaders();
  }
};

TEST_F(GoogleFontServiceInputResourceTest, Creation) {
  ResetUserAgent("Chromezilla");

  scoped_ptr<GoogleFontServiceInputResource> resource;

  GoogleUrl url1("efpeRO#@($@#K$!@($");
  resource.reset(GoogleFontServiceInputResource::Make(url1, rewrite_driver()));
  EXPECT_TRUE(resource.get() == NULL);

  GoogleUrl url2("http://example.com/foo.css");
  resource.reset(GoogleFontServiceInputResource::Make(url2, rewrite_driver()));
  EXPECT_TRUE(resource.get() == NULL);

  GoogleUrl url3(kRoboto);
  resource.reset(GoogleFontServiceInputResource::Make(url3, rewrite_driver()));
  ASSERT_TRUE(resource.get() != NULL);
  EXPECT_EQ(kRoboto, resource->url());
  EXPECT_EQ(
      "gfnt://fonts.googleapis.com/css?family=Roboto&X-PS-UA=Chromezilla",
      resource->cache_key());

  GoogleUrl url4(kRobotoSsl);
  resource.reset(GoogleFontServiceInputResource::Make(url4, rewrite_driver()));
  ASSERT_TRUE(resource.get() != NULL);
  EXPECT_EQ(kRobotoSsl, resource->url());
  EXPECT_EQ(
      "gfnts://fonts.googleapis.com/css?family=Roboto&X-PS-UA=Chromezilla",
      resource->cache_key());
}

TEST_F(GoogleFontServiceInputResourceTest, Load) {
  GoogleUrl url(kRoboto);
  ResetUserAgent("Chromezilla");

  ResourcePtr resource(
      GoogleFontServiceInputResource::Make(url, rewrite_driver()));
  ASSERT_TRUE(resource.get() != NULL);
  MockResourceCallback callback(resource,
                                server_context()->thread_system());
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback);
  EXPECT_TRUE(callback.done());
  EXPECT_TRUE(callback.success());
  EXPECT_EQ("font_chromezilla", resource->ExtractUncompressedContents());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());

  // Make sure it's cached.
  ResourcePtr resource2(
      GoogleFontServiceInputResource::Make(url, rewrite_driver()));
  ASSERT_TRUE(resource2.get() != NULL);
  MockResourceCallback callback2(resource2,
                                 server_context()->thread_system());
  resource2->LoadAsync(Resource::kReportFailureIfNotCacheable,
                       rewrite_driver()->request_context(),
                       &callback2);
  EXPECT_TRUE(callback2.done());
  EXPECT_TRUE(callback2.success());
  EXPECT_EQ("font_chromezilla", resource2->ExtractUncompressedContents());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());

  // But that different UA gets different string.
  ResetUserAgent("Safieri");
  ResourcePtr resource3(
      GoogleFontServiceInputResource::Make(url, rewrite_driver()));
  ASSERT_TRUE(resource3.get() != NULL);
  MockResourceCallback callback3(resource3,
                                 server_context()->thread_system());
  resource3->LoadAsync(Resource::kReportFailureIfNotCacheable,
                       rewrite_driver()->request_context(),
                       &callback3);
  EXPECT_TRUE(callback3.done());
  EXPECT_TRUE(callback3.success());
  EXPECT_EQ("font_safieri", resource3->ExtractUncompressedContents());
  EXPECT_EQ(2, counting_url_async_fetcher()->fetch_count());
}

TEST_F(GoogleFontServiceInputResourceTest, UANormalization) {
  const char kIE7a[] =
      "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; "
      ".NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";

  GoogleUrl url(kRoboto);
  scoped_ptr<GoogleUrl> url_plus_ua(url.CopyAndAddQueryParam("UA", kIE7a));
  ResponseHeaders response_headers;
  SetDefaultLongCacheHeaders(&kContentTypeCss, &response_headers);
  response_headers.SetDateAndCaching(
      timer()->NowMs(), 86400 * Timer::kSecondMs, ", private");
  SetFetchResponse(url_plus_ua->Spec(), response_headers, "font_IE7");

  // Try fetches with a couple of possible aliases. The one we uploaded it under
  // is first, since it's the only one the fetcher replies to.
  ResetUserAgent(kIE7a);

  ResourcePtr resource(
      GoogleFontServiceInputResource::Make(url, rewrite_driver()));
  ASSERT_TRUE(resource.get() != NULL);
  MockResourceCallback callback(resource,
                                server_context()->thread_system());
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback);
  EXPECT_TRUE(callback.done());
  EXPECT_TRUE(callback.success());
  EXPECT_EQ("font_IE7", resource->ExtractUncompressedContents());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());

  // Different list of .NET versions.
  const char kIE7b[] =
      "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; "
      ".NET CLR 2.0.50727; .NET4.0C; .NET4.0E)";
  ResetUserAgent(kIE7b);

  ResourcePtr resource2(
      GoogleFontServiceInputResource::Make(url, rewrite_driver()));
  ASSERT_TRUE(resource2.get() != NULL);
  MockResourceCallback callback2(resource2,
                                 server_context()->thread_system());
  resource2->LoadAsync(Resource::kReportFailureIfNotCacheable,
                       rewrite_driver()->request_context(),
                       &callback2);
  EXPECT_TRUE(callback2.done());
  EXPECT_TRUE(callback2.success());
  EXPECT_EQ("font_IE7", resource->ExtractUncompressedContents());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());
}

TEST_F(GoogleFontServiceInputResourceTest, LoadParallel) {
  GoogleUrl url(kRoboto);
  SetupWaitFetcher();

  ResetUserAgent("Chromezilla");
  ResourcePtr resource(
      GoogleFontServiceInputResource::Make(url, rewrite_driver()));
  ASSERT_TRUE(resource.get() != NULL);
  MockResourceCallback callback(resource,
                                server_context()->thread_system());
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback);
  EXPECT_FALSE(callback.done());

  ResetUserAgent("Safieri");
  ResourcePtr resource2(
      GoogleFontServiceInputResource::Make(url, rewrite_driver()));
  ASSERT_TRUE(resource2.get() != NULL);
  MockResourceCallback callback2(resource2,
                                 server_context()->thread_system());
  resource2->LoadAsync(Resource::kReportFailureIfNotCacheable,
                       rewrite_driver()->request_context(),
                       &callback2);
  EXPECT_FALSE(callback2.done());

  CallFetcherCallbacks();

  ASSERT_TRUE(callback.done());
  EXPECT_TRUE(callback.success());
  EXPECT_EQ("font_chromezilla", resource->ExtractUncompressedContents());

  ASSERT_TRUE(callback2.done());
  EXPECT_TRUE(callback2.success());
  EXPECT_EQ("font_safieri", resource2->ExtractUncompressedContents());
}

TEST_F(GoogleFontServiceInputResourceTest, FetchFailure) {
  SetFetchFailOnUnexpected(false);

  // Regression test --- don't crash when fetch fails.
  // Bug discovered by accident due to a bug in a test.
  ResetUserAgent("Huhzilla");
  GoogleUrl url(kRoboto);
  ResourcePtr resource(
      GoogleFontServiceInputResource::Make(url, rewrite_driver()));
  ASSERT_TRUE(resource.get() != NULL);
  MockResourceCallback callback(resource,
                                server_context()->thread_system());
  resource->LoadAsync(Resource::kLoadEvenIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback);
  EXPECT_TRUE(callback.done());
  EXPECT_FALSE(callback.success());
  EXPECT_EQ("", resource->ExtractUncompressedContents());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());
}

TEST_F(GoogleFontServiceInputResourceTest, DontLoadNonCss) {
  ResetUserAgent("Chromezilla");

  GoogleUrl non_css_url(kNonCss);
  ResourcePtr resource(
      GoogleFontServiceInputResource::Make(non_css_url, rewrite_driver()));
  ASSERT_TRUE(resource.get() != NULL);
  MockResourceCallback callback(resource,
                                server_context()->thread_system());
  resource->LoadAsync(Resource::kLoadEvenIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback);
  EXPECT_TRUE(callback.done());
  EXPECT_FALSE(resource->HttpStatusOk());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());

  // Make sure we don't end up caching a success, either.
  ResourcePtr resource2(
      GoogleFontServiceInputResource::Make(non_css_url, rewrite_driver()));
  ASSERT_TRUE(resource2.get() != NULL);
  MockResourceCallback callback2(resource2,
                                 server_context()->thread_system());
  resource2->LoadAsync(Resource::kLoadEvenIfNotCacheable,
                       rewrite_driver()->request_context(),
                       &callback2);
  EXPECT_TRUE(callback2.done());
  EXPECT_FALSE(resource->HttpStatusOk());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());
}

TEST_F(GoogleFontServiceInputResourceTest, IsFontServiceUrlTest) {
  GoogleUrl roboto_url(kRoboto);
  EXPECT_TRUE(GoogleFontServiceInputResource::IsFontServiceUrl(roboto_url));

  GoogleUrl roboto_ssl_url(kRobotoSsl);
  EXPECT_TRUE(GoogleFontServiceInputResource::IsFontServiceUrl(roboto_ssl_url));

  GoogleUrl example_url("http://example.com/");
  EXPECT_FALSE(GoogleFontServiceInputResource::IsFontServiceUrl(example_url));
}

}  // namespace

}  // namespace net_instaweb
