// Copyright (c) 2012 The Chromium 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 "net/url_request/url_request_filter.h"

#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/request_priority.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

class TestURLRequestInterceptor : public URLRequestInterceptor {
 public:
  TestURLRequestInterceptor() : job_(nullptr) {}
  ~TestURLRequestInterceptor() override {}

  // URLRequestInterceptor implementation:
  URLRequestJob* MaybeInterceptRequest(
      URLRequest* request,
      NetworkDelegate* network_delegate) const override {
    job_ = new URLRequestTestJob(request, network_delegate);
    return job_;
  }

  // Is |job| the URLRequestJob generated during interception?
  bool WasLastJobCreated(URLRequestJob* job) const {
    return job_ && job_ == job;
  }

 private:
  mutable URLRequestTestJob* job_;

  DISALLOW_COPY_AND_ASSIGN(TestURLRequestInterceptor);
};

TEST(URLRequestFilter, BasicMatching) {
  TestDelegate delegate;
  TestURLRequestContext request_context;
  URLRequestFilter* filter = URLRequestFilter::GetInstance();

  const GURL kUrl1("http://foo.com/");
  scoped_ptr<URLRequest> request1(
      request_context.CreateRequest(kUrl1, DEFAULT_PRIORITY, &delegate));

  const GURL kUrl2("http://bar.com/");
  scoped_ptr<URLRequest> request2(
      request_context.CreateRequest(kUrl2, DEFAULT_PRIORITY, &delegate));

  // Check AddUrlInterceptor checks for invalid URLs.
  EXPECT_FALSE(filter->AddUrlInterceptor(
      GURL(),
      scoped_ptr<URLRequestInterceptor>(new TestURLRequestInterceptor())));

  // Check URLRequestInterceptor URL matching.
  filter->ClearHandlers();
  TestURLRequestInterceptor* interceptor = new TestURLRequestInterceptor();
  EXPECT_TRUE(filter->AddUrlInterceptor(
      kUrl1, scoped_ptr<URLRequestInterceptor>(interceptor)));
  {
    scoped_ptr<URLRequestJob> found(
        filter->MaybeInterceptRequest(request1.get(), NULL));
    EXPECT_TRUE(interceptor->WasLastJobCreated(found.get()));
  }
  EXPECT_EQ(filter->hit_count(), 1);

  // Check we don't match other URLs.
  EXPECT_TRUE(filter->MaybeInterceptRequest(request2.get(), NULL) == NULL);
  EXPECT_EQ(1, filter->hit_count());

  // Check we can remove URL matching.
  filter->RemoveUrlHandler(kUrl1);
  EXPECT_TRUE(filter->MaybeInterceptRequest(request1.get(), NULL) == NULL);
  EXPECT_EQ(1, filter->hit_count());

  // Check hostname matching.
  filter->ClearHandlers();
  EXPECT_EQ(0, filter->hit_count());
  interceptor = new TestURLRequestInterceptor();
  filter->AddHostnameInterceptor(
      kUrl1.scheme(), kUrl1.host(),
      scoped_ptr<URLRequestInterceptor>(interceptor));
  {
    scoped_ptr<URLRequestJob> found(
        filter->MaybeInterceptRequest(request1.get(), NULL));
    EXPECT_TRUE(interceptor->WasLastJobCreated(found.get()));
  }
  EXPECT_EQ(1, filter->hit_count());

  // Check we don't match other hostnames.
  EXPECT_TRUE(filter->MaybeInterceptRequest(request2.get(), NULL) == NULL);
  EXPECT_EQ(1, filter->hit_count());

  // Check we can remove hostname matching.
  filter->RemoveHostnameHandler(kUrl1.scheme(), kUrl1.host());
  EXPECT_TRUE(filter->MaybeInterceptRequest(request1.get(), NULL) == NULL);
  EXPECT_EQ(1, filter->hit_count());

  filter->ClearHandlers();
}

}  // namespace

}  // namespace net
