// Copyright 2015 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 "services/proxy_resolver/proxy_resolver_factory_impl.h"

#include <utility>

#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/base/completion_once_callback.h"
#include "net/base/test_completion_callback.h"
#include "net/proxy_resolution/mock_proxy_resolver.h"
#include "net/proxy_resolution/proxy_resolver_v8_tracing.h"
#include "net/test/event_waiter.h"
#include "net/test/gtest_util.h"
#include "services/service_manager/public/cpp/service_keepalive.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using net::test::IsError;
using net::test::IsOk;

namespace proxy_resolver {
namespace {

const char kScriptData[] = "FooBarBaz";

class FakeProxyResolver : public net::ProxyResolverV8Tracing {
 public:
  explicit FakeProxyResolver(const base::Closure& on_destruction)
      : on_destruction_(on_destruction) {}

  ~FakeProxyResolver() override { on_destruction_.Run(); }

 private:
  // net::ProxyResolverV8Tracing overrides.
  void GetProxyForURL(const GURL& url,
                      net::ProxyInfo* results,
                      net::CompletionOnceCallback callback,
                      std::unique_ptr<net::ProxyResolver::Request>* request,
                      std::unique_ptr<Bindings> bindings) override {}

  const base::Closure on_destruction_;
};

enum Event {
  NONE,
  RESOLVER_CREATED,
  CONNECTION_ERROR,
  RESOLVER_DESTROYED,
};

class TestProxyResolverFactory : public net::ProxyResolverV8TracingFactory {
 public:
  struct PendingRequest {
    std::unique_ptr<net::ProxyResolverV8Tracing>* resolver;
    net::CompletionOnceCallback callback;
  };

  explicit TestProxyResolverFactory(net::EventWaiter<Event>* waiter)
      : waiter_(waiter) {}

  ~TestProxyResolverFactory() override {}

  void CreateProxyResolverV8Tracing(
      const scoped_refptr<net::PacFileData>& pac_script,
      std::unique_ptr<net::ProxyResolverV8Tracing::Bindings> bindings,
      std::unique_ptr<net::ProxyResolverV8Tracing>* resolver,
      net::CompletionOnceCallback callback,
      std::unique_ptr<net::ProxyResolverFactory::Request>* request) override {
    requests_handled_++;
    waiter_->NotifyEvent(RESOLVER_CREATED);
    EXPECT_EQ(base::ASCIIToUTF16(kScriptData), pac_script->utf16());
    EXPECT_TRUE(resolver);
    pending_request_.reset(new PendingRequest);
    pending_request_->resolver = resolver;
    pending_request_->callback = std::move(callback);

    ASSERT_TRUE(bindings);

    bindings->Alert(base::ASCIIToUTF16("alert"));
    bindings->OnError(10, base::ASCIIToUTF16("error"));
    EXPECT_TRUE(bindings->GetHostResolver());
  }

  size_t requests_handled() { return requests_handled_; }
  PendingRequest* pending_request() { return pending_request_.get(); }

 private:
  net::EventWaiter<Event>* waiter_;
  size_t requests_handled_ = 0;
  std::unique_ptr<PendingRequest> pending_request_;
};

class TestProxyResolverFactoryImpl : public ProxyResolverFactoryImpl {
 public:
  explicit TestProxyResolverFactoryImpl(
      std::unique_ptr<net::ProxyResolverV8TracingFactory>
          proxy_resolver_factory)
      : ProxyResolverFactoryImpl(std::move(proxy_resolver_factory)) {}
};

}  // namespace

class ProxyResolverFactoryImplTest
    : public testing::Test,
      public mojom::ProxyResolverFactoryRequestClient,
      public service_manager::ServiceKeepalive::Observer {
 public:
  ProxyResolverFactoryImplTest()
      : service_keepalive_(
            static_cast<service_manager::ServiceBinding*>(nullptr),
            base::TimeDelta()) {
    service_keepalive_.AddObserver(this);
    std::unique_ptr<TestProxyResolverFactory> test_factory =
        std::make_unique<TestProxyResolverFactory>(&waiter_);
    mock_factory_ = test_factory.get();
    mock_factory_impl_ =
        std::make_unique<TestProxyResolverFactoryImpl>(std::move(test_factory));
    mock_factory_impl_->BindRequest(mojo::MakeRequest(&factory_),
                                    &service_keepalive_);
  }

  ~ProxyResolverFactoryImplTest() override {
    service_keepalive_.RemoveObserver(this);
  }

  void OnConnectionError() { waiter_.NotifyEvent(CONNECTION_ERROR); }

  void OnFakeProxyInstanceDestroyed() {
    instances_destroyed_++;
    waiter_.NotifyEvent(RESOLVER_DESTROYED);
  }

  void ReportResult(int32_t error) override {
    std::move(create_callback_).Run(error);
  }

  void Alert(const std::string& message) override {}

  void OnError(int32_t line_number, const std::string& message) override {}

  void ResolveDns(std::unique_ptr<net::HostResolver::RequestInfo> request_info,
                  mojom::HostResolverRequestClientPtr client) override {}

  void WaitForNoServiceRefs() {
    DCHECK(!service_keepalive_ref_run_loop_);

    if (service_keepalive_.HasNoRefs())
      return;

    service_keepalive_ref_run_loop_ = std::make_unique<base::RunLoop>();
    service_keepalive_ref_run_loop_->Run();
    service_keepalive_ref_run_loop_.reset();

    EXPECT_TRUE(service_keepalive_.HasNoRefs());
  }

 protected:
  // service_manager::ServiceKeepalive::Observer:
  void OnIdleTimeout() override {
    if (service_keepalive_ref_run_loop_)
      service_keepalive_ref_run_loop_->Quit();
  }

  base::test::ScopedTaskEnvironment task_environment_;
  std::unique_ptr<TestProxyResolverFactoryImpl> mock_factory_impl_;
  TestProxyResolverFactory* mock_factory_;
  mojom::ProxyResolverFactoryPtr factory_;

  service_manager::ServiceKeepalive service_keepalive_;
  std::unique_ptr<base::RunLoop> service_keepalive_ref_run_loop_;

  int instances_destroyed_ = 0;
  net::CompletionOnceCallback create_callback_;

  net::EventWaiter<Event> waiter_;
};

TEST_F(ProxyResolverFactoryImplTest, DisconnectProxyResolverClient) {
  mojom::ProxyResolverPtr proxy_resolver;
  mojom::ProxyResolverFactoryRequestClientPtr client_ptr;
  mojo::Binding<ProxyResolverFactoryRequestClient> client_binding(
      this, mojo::MakeRequest(&client_ptr));
  factory_->CreateResolver(kScriptData, mojo::MakeRequest(&proxy_resolver),
                           std::move(client_ptr));
  proxy_resolver.set_connection_error_handler(
      base::Bind(&ProxyResolverFactoryImplTest::OnConnectionError,
                 base::Unretained(this)));
  waiter_.WaitForEvent(RESOLVER_CREATED);
  EXPECT_EQ(0, instances_destroyed_);
  ASSERT_EQ(1u, mock_factory_->requests_handled());
  net::TestCompletionCallback create_callback;
  create_callback_ = create_callback.callback();
  ASSERT_TRUE(mock_factory_->pending_request());
  mock_factory_->pending_request()->resolver->reset(new FakeProxyResolver(
      base::Bind(&ProxyResolverFactoryImplTest::OnFakeProxyInstanceDestroyed,
                 base::Unretained(this))));
  std::move(mock_factory_->pending_request()->callback).Run(net::OK);
  EXPECT_THAT(create_callback.WaitForResult(), IsOk());
  EXPECT_FALSE(service_keepalive_.HasNoRefs());

  proxy_resolver.reset();
  waiter_.WaitForEvent(RESOLVER_DESTROYED);
  EXPECT_EQ(1, instances_destroyed_);
  EXPECT_FALSE(service_keepalive_.HasNoRefs());

  task_environment_.RunUntilIdle();
  EXPECT_FALSE(service_keepalive_.HasNoRefs());

  factory_.reset();
  WaitForNoServiceRefs();
}

// Same as above, but disconnect the factory right after the CreateResolver
// call, which should not prevent the request from succeeding.
TEST_F(ProxyResolverFactoryImplTest, DisconnectProxyResolverFactory) {
  mojom::ProxyResolverPtr proxy_resolver;
  mojom::ProxyResolverFactoryRequestClientPtr client_ptr;
  mojo::Binding<ProxyResolverFactoryRequestClient> client_binding(
      this, mojo::MakeRequest(&client_ptr));
  factory_->CreateResolver(kScriptData, mojo::MakeRequest(&proxy_resolver),
                           std::move(client_ptr));
  factory_.reset();
  proxy_resolver.set_connection_error_handler(
      base::Bind(&ProxyResolverFactoryImplTest::OnConnectionError,
                 base::Unretained(this)));
  waiter_.WaitForEvent(RESOLVER_CREATED);
  EXPECT_EQ(0, instances_destroyed_);
  ASSERT_EQ(1u, mock_factory_->requests_handled());
  net::TestCompletionCallback create_callback;
  create_callback_ = create_callback.callback();
  ASSERT_TRUE(mock_factory_->pending_request());
  mock_factory_->pending_request()->resolver->reset(new FakeProxyResolver(
      base::Bind(&ProxyResolverFactoryImplTest::OnFakeProxyInstanceDestroyed,
                 base::Unretained(this))));
  std::move(mock_factory_->pending_request()->callback).Run(net::OK);
  EXPECT_THAT(create_callback.WaitForResult(), IsOk());
  EXPECT_FALSE(service_keepalive_.HasNoRefs());

  task_environment_.RunUntilIdle();
  EXPECT_FALSE(service_keepalive_.HasNoRefs());

  proxy_resolver.reset();
  waiter_.WaitForEvent(RESOLVER_DESTROYED);
  EXPECT_EQ(1, instances_destroyed_);

  WaitForNoServiceRefs();
}

TEST_F(ProxyResolverFactoryImplTest, Error) {
  mojom::ProxyResolverPtr proxy_resolver;
  mojom::ProxyResolverFactoryRequestClientPtr client_ptr;
  mojo::Binding<ProxyResolverFactoryRequestClient> client_binding(
      this, mojo::MakeRequest(&client_ptr));
  factory_->CreateResolver(kScriptData, mojo::MakeRequest(&proxy_resolver),
                           std::move(client_ptr));
  proxy_resolver.set_connection_error_handler(
      base::Bind(&ProxyResolverFactoryImplTest::OnConnectionError,
                 base::Unretained(this)));
  waiter_.WaitForEvent(RESOLVER_CREATED);
  EXPECT_EQ(0, instances_destroyed_);
  ASSERT_EQ(1u, mock_factory_->requests_handled());
  net::TestCompletionCallback create_callback;
  create_callback_ = create_callback.callback();
  ASSERT_TRUE(mock_factory_->pending_request());
  std::move(mock_factory_->pending_request()->callback)
      .Run(net::ERR_PAC_SCRIPT_FAILED);
  EXPECT_THAT(create_callback.WaitForResult(),
              IsError(net::ERR_PAC_SCRIPT_FAILED));
}

TEST_F(ProxyResolverFactoryImplTest, DisconnectClientDuringResolverCreation) {
  mojom::ProxyResolverPtr proxy_resolver;
  mojom::ProxyResolverFactoryRequestClientPtr client_ptr;
  mojo::Binding<ProxyResolverFactoryRequestClient> client_binding(
      this, mojo::MakeRequest(&client_ptr));
  factory_->CreateResolver(kScriptData, mojo::MakeRequest(&proxy_resolver),
                           std::move(client_ptr));
  proxy_resolver.set_connection_error_handler(
      base::Bind(&ProxyResolverFactoryImplTest::OnConnectionError,
                 base::Unretained(this)));
  waiter_.WaitForEvent(RESOLVER_CREATED);
  EXPECT_EQ(0, instances_destroyed_);
  ASSERT_EQ(1u, mock_factory_->requests_handled());
  client_binding.Close();
  waiter_.WaitForEvent(CONNECTION_ERROR);
}

TEST_F(ProxyResolverFactoryImplTest, MultipleFactories) {
  // Creating |factory_| should have resulted in an outstanding service
  // reference.
  EXPECT_FALSE(service_keepalive_.HasNoRefs());

  // Creating another shouldn't change that.
  mojom::ProxyResolverFactoryPtr factory2;
  mock_factory_impl_->BindRequest(mojo::MakeRequest(&factory2),
                                  &service_keepalive_);
  EXPECT_FALSE(service_keepalive_.HasNoRefs());

  // Destroying one factory while keeping the other around should not release
  // the reference.
  factory_.reset();
  task_environment_.RunUntilIdle();
  EXPECT_FALSE(service_keepalive_.HasNoRefs());

  // Destroying the second factory should release the reference.
  factory2.reset();
  WaitForNoServiceRefs();

  // Test that creating and then destroying a new factory gets and releases a
  // reference again.
  mock_factory_impl_->BindRequest(mojo::MakeRequest(&factory2),
                                  &service_keepalive_);
  EXPECT_FALSE(service_keepalive_.HasNoRefs());
  factory2.reset();
  WaitForNoServiceRefs();
}

}  // namespace proxy_resolver
