// Copyright (c) 2011 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 "content/browser/resolve_proxy_msg_helper.h"

#include <tuple>

#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "content/common/view_messages.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "ipc/ipc_test_sink.h"
#include "net/base/net_errors.h"
#include "net/proxy_resolution/proxy_info.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/mojom/proxy_lookup_client.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

class TestResolveProxyMsgHelper : public ResolveProxyMsgHelper {
 public:
  // Incoming ProxyLookupClientPtrs are written to |proxy_lookup_client|.
  explicit TestResolveProxyMsgHelper(
      IPC::Listener* listener,
      network::mojom::ProxyLookupClientPtr* proxy_lookup_client)
      : ResolveProxyMsgHelper(0 /* renderer_process_host_id */),
        listener_(listener),
        proxy_lookup_client_(proxy_lookup_client) {}

  bool Send(IPC::Message* message) override {
    // Shouldn't be calling Send() if there are no live references to |this|.
    EXPECT_TRUE(HasAtLeastOneRef());

    listener_->OnMessageReceived(*message);
    delete message;
    return true;
  }

  bool SendRequestToNetworkService(
      const GURL& url,
      network::mojom::ProxyLookupClientPtr proxy_lookup_client) override {
    // Only one request should be send at a time.
    EXPECT_FALSE(*proxy_lookup_client_);

    if (fail_to_send_request_)
      return false;

    pending_url_ = url;
    *proxy_lookup_client_ = std::move(proxy_lookup_client);
    return true;
  }

  const GURL& pending_url() const { return pending_url_; }

  void set_fail_to_send_request(bool fail_to_send_request) {
    fail_to_send_request_ = fail_to_send_request;
  }

 protected:
  ~TestResolveProxyMsgHelper() override {}

  IPC::Listener* listener_;

  bool fail_to_send_request_ = false;

  network::mojom::ProxyLookupClientPtr* proxy_lookup_client_;
  GURL pending_url_;

  DISALLOW_COPY_AND_ASSIGN(TestResolveProxyMsgHelper);
};

class ResolveProxyMsgHelperTest : public testing::Test, public IPC::Listener {
 public:
  struct PendingResult {
    PendingResult(bool result,
                  const std::string& proxy_list)
        : result(result), proxy_list(proxy_list) {
    }

    bool result;
    std::string proxy_list;
  };

  ResolveProxyMsgHelperTest()
      : helper_(base::MakeRefCounted<TestResolveProxyMsgHelper>(
            this,
            &proxy_lookup_client_)) {
    test_sink_.AddFilter(this);
  }

 protected:
  const PendingResult* pending_result() const { return pending_result_.get(); }

  void clear_pending_result() {
    pending_result_.reset();
  }

  IPC::Message* GenerateReply() {
    bool temp_bool;
    std::string temp_string;
    ViewHostMsg_ResolveProxy message(GURL(), &temp_bool, &temp_string);
    return IPC::SyncMessage::GenerateReply(&message);
  }

  bool OnMessageReceived(const IPC::Message& msg) override {
    ViewHostMsg_ResolveProxy::ReplyParam reply_data;
    EXPECT_TRUE(ViewHostMsg_ResolveProxy::ReadReplyParam(&msg, &reply_data));
    DCHECK(!pending_result_.get());
    pending_result_.reset(
        new PendingResult(std::get<0>(reply_data), std::get<1>(reply_data)));
    test_sink_.ClearMessages();
    return true;
  }

  TestBrowserThreadBundle thread_bundle_;

  scoped_refptr<TestResolveProxyMsgHelper> helper_;
  std::unique_ptr<PendingResult> pending_result_;

  network::mojom::ProxyLookupClientPtr proxy_lookup_client_;

  IPC::TestSink test_sink_;
};

// Issue three sequential requests -- each should succeed.
TEST_F(ResolveProxyMsgHelperTest, Sequential) {
  GURL url1("http://www.google1.com/");
  GURL url2("http://www.google2.com/");
  GURL url3("http://www.google3.com/");

  // Messages are deleted by the sink.
  IPC::Message* msg1 = GenerateReply();
  IPC::Message* msg2 = GenerateReply();
  IPC::Message* msg3 = GenerateReply();

  // Execute each request sequentially (so there are never 2 requests
  // outstanding at the same time).

  helper_->OnResolveProxy(url1, msg1);

  // There should be a pending proxy lookup request. Respond to it.
  EXPECT_EQ(url1, helper_->pending_url());
  ASSERT_TRUE(proxy_lookup_client_);
  net::ProxyInfo proxy_info;
  proxy_info.UseNamedProxy("result1:80");
  proxy_lookup_client_->OnProxyLookupComplete(proxy_info);
  proxy_lookup_client_.reset();
  base::RunLoop().RunUntilIdle();

  // Check result.
  EXPECT_EQ(true, pending_result()->result);
  EXPECT_EQ("PROXY result1:80", pending_result()->proxy_list);
  clear_pending_result();

  helper_->OnResolveProxy(url2, msg2);

  EXPECT_EQ(url2, helper_->pending_url());
  ASSERT_TRUE(proxy_lookup_client_);
  proxy_info.UseNamedProxy("result2:80");
  proxy_lookup_client_->OnProxyLookupComplete(proxy_info);
  proxy_lookup_client_.reset();
  base::RunLoop().RunUntilIdle();

  // Check result.
  EXPECT_EQ(true, pending_result()->result);
  EXPECT_EQ("PROXY result2:80", pending_result()->proxy_list);
  clear_pending_result();

  helper_->OnResolveProxy(url3, msg3);

  EXPECT_EQ(url3, helper_->pending_url());
  ASSERT_TRUE(proxy_lookup_client_);
  proxy_info.UseNamedProxy("result3:80");
  proxy_lookup_client_->OnProxyLookupComplete(proxy_info);
  base::RunLoop().RunUntilIdle();

  // Check result.
  EXPECT_EQ(true, pending_result()->result);
  EXPECT_EQ("PROXY result3:80", pending_result()->proxy_list);
  clear_pending_result();
}

// Issue a request while one is already in progress -- should be queued.
TEST_F(ResolveProxyMsgHelperTest, QueueRequests) {
  GURL url1("http://www.google1.com/");
  GURL url2("http://www.google2.com/");
  GURL url3("http://www.google3.com/");

  IPC::Message* msg1 = GenerateReply();
  IPC::Message* msg2 = GenerateReply();
  IPC::Message* msg3 = GenerateReply();

  // Start three requests. All the requests will be pending.

  helper_->OnResolveProxy(url1, msg1);
  helper_->OnResolveProxy(url2, msg2);
  helper_->OnResolveProxy(url3, msg3);

  // Complete first request.
  EXPECT_EQ(url1, helper_->pending_url());
  ASSERT_TRUE(proxy_lookup_client_);
  net::ProxyInfo proxy_info;
  proxy_info.UseNamedProxy("result1:80");
  proxy_lookup_client_->OnProxyLookupComplete(proxy_info);
  proxy_lookup_client_.reset();
  base::RunLoop().RunUntilIdle();

  // Check result.
  EXPECT_EQ(true, pending_result()->result);
  EXPECT_EQ("PROXY result1:80", pending_result()->proxy_list);
  clear_pending_result();

  // Complete second request.
  EXPECT_EQ(url2, helper_->pending_url());
  ASSERT_TRUE(proxy_lookup_client_);
  proxy_info.UseNamedProxy("result2:80");
  proxy_lookup_client_->OnProxyLookupComplete(proxy_info);
  proxy_lookup_client_.reset();
  base::RunLoop().RunUntilIdle();

  // Check result.
  EXPECT_EQ(true, pending_result()->result);
  EXPECT_EQ("PROXY result2:80", pending_result()->proxy_list);
  clear_pending_result();

  // Complete third request.
  EXPECT_EQ(url3, helper_->pending_url());
  ASSERT_TRUE(proxy_lookup_client_);
  proxy_info.UseNamedProxy("result3:80");
  proxy_lookup_client_->OnProxyLookupComplete(proxy_info);
  base::RunLoop().RunUntilIdle();

  // Check result.
  EXPECT_EQ(true, pending_result()->result);
  EXPECT_EQ("PROXY result3:80", pending_result()->proxy_list);
  clear_pending_result();
}

// Delete the helper while a request is in progress and others are pending.
TEST_F(ResolveProxyMsgHelperTest, CancelPendingRequests) {
  GURL url1("http://www.google1.com/");
  GURL url2("http://www.google2.com/");
  GURL url3("http://www.google3.com/");

  // They will be deleted by the request's cancellation.
  IPC::Message* msg1 = GenerateReply();
  IPC::Message* msg2 = GenerateReply();
  IPC::Message* msg3 = GenerateReply();

  // Start three requests. Since the proxy resolver is async, all the
  // requests will be pending.

  helper_->OnResolveProxy(url1, msg1);
  helper_->OnResolveProxy(url2, msg2);
  helper_->OnResolveProxy(url3, msg3);

  // Check the first request is pending.
  EXPECT_EQ(url1, helper_->pending_url());
  ASSERT_TRUE(proxy_lookup_client_);

  // Release a reference. The |helper_| will not be deleted, since there's a
  // pending resolution.
  helper_ = nullptr;
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(proxy_lookup_client_.is_bound());
  EXPECT_FALSE(proxy_lookup_client_.encountered_error());

  // Send Mojo message on the pipe.
  net::ProxyInfo proxy_info;
  proxy_info.UseNamedProxy("result1:80");
  proxy_lookup_client_->OnProxyLookupComplete(proxy_info);

  // Spinning the message loop results in the helper being destroyed and closing
  // the pipe.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(!proxy_lookup_client_.is_bound() ||
              proxy_lookup_client_.encountered_error());
  // The result should not have been sent.
  EXPECT_FALSE(pending_result());

  // It should also be the case that msg1, msg2, msg3 were deleted by the
  // cancellation. (Else will show up as a leak).
}

// Issue a request that fails.
TEST_F(ResolveProxyMsgHelperTest, RequestFails) {
  GURL url("http://www.google.com/");

  // Message will be deleted by the sink.
  IPC::Message* msg = GenerateReply();

  helper_->OnResolveProxy(url, msg);

  // There should be a pending proxy lookup request. Respond to it.
  EXPECT_EQ(url, helper_->pending_url());
  ASSERT_TRUE(proxy_lookup_client_);
  proxy_lookup_client_->OnProxyLookupComplete(base::nullopt);
  base::RunLoop().RunUntilIdle();

  // Check result.
  EXPECT_EQ(false, pending_result()->result);
  EXPECT_EQ("", pending_result()->proxy_list);
  clear_pending_result();
}

// Issue a request, only to have the Mojo pipe closed.
TEST_F(ResolveProxyMsgHelperTest, PipeClosed) {
  GURL url("http://www.google.com/");

  // Message will be deleted by the sink.
  IPC::Message* msg = GenerateReply();

  helper_->OnResolveProxy(url, msg);

  // There should be a pending proxy lookup request. Respond to it by closing
  // the pipe.
  EXPECT_EQ(url, helper_->pending_url());
  ASSERT_TRUE(proxy_lookup_client_);
  proxy_lookup_client_.reset();
  base::RunLoop().RunUntilIdle();

  // Check result.
  EXPECT_EQ(false, pending_result()->result);
  EXPECT_EQ("", pending_result()->proxy_list);
  clear_pending_result();
}

// Fail to send a request to the network service.
TEST_F(ResolveProxyMsgHelperTest, FailToSendRequest) {
  GURL url("http://www.google.com/");

  // Message will be deleted by the sink.
  IPC::Message* msg = GenerateReply();

  helper_->set_fail_to_send_request(true);

  helper_->OnResolveProxy(url, msg);
  // No request should be pending.
  EXPECT_TRUE(helper_->pending_url().is_empty());

  // Check result.
  EXPECT_EQ(false, pending_result()->result);
  EXPECT_EQ("", pending_result()->proxy_list);
  clear_pending_result();
}

// Make sure if mojo callback is invoked after last externally owned reference
// is released, there is no crash.
// Regression test for https://crbug.com/870675
TEST_F(ResolveProxyMsgHelperTest, Lifetime) {
  GURL url("http://www.google1.com/");

  // Messages are deleted by the sink.
  IPC::Message* msg = GenerateReply();

  helper_->OnResolveProxy(url, msg);

  // There should be a pending proxy lookup request. Respond to it.
  EXPECT_EQ(url, helper_->pending_url());
  ASSERT_TRUE(proxy_lookup_client_);

  // Release the |helper_| pointer. The object should keep a reference to
  // itself, so should not be deleted.
  helper_ = nullptr;
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(proxy_lookup_client_.is_bound());
  EXPECT_FALSE(proxy_lookup_client_.encountered_error());

  // Send Mojo message on the pipe.
  net::ProxyInfo proxy_info;
  proxy_info.UseNamedProxy("result1:80");
  proxy_lookup_client_->OnProxyLookupComplete(proxy_info);

  // Spinning the message loop results in the helper being destroyed and closing
  // the pipe.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(!proxy_lookup_client_.is_bound() ||
              proxy_lookup_client_.encountered_error());
  // The result should not have been sent.
  EXPECT_FALSE(pending_result());
}

}  // namespace content
