//
// Copyright (C) 2011 The Android Open Source Project
//
// 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.
//

#include "update_engine/chrome_browser_proxy_resolver.h"

#include <deque>
#include <string>
#include <vector>

#include <gtest/gtest.h>

#include <base/bind.h>
#include <brillo/make_unique_ptr.h>
#include <brillo/message_loops/fake_message_loop.h>

#include "libcros/dbus-proxies.h"
#include "libcros/dbus-proxy-mocks.h"
#include "update_engine/dbus_test_utils.h"

using ::testing::Return;
using ::testing::StrEq;
using ::testing::_;
using brillo::MessageLoop;
using org::chromium::LibCrosServiceInterfaceProxyMock;
using org::chromium::UpdateEngineLibcrosProxyResolvedInterfaceProxyMock;
using std::deque;
using std::string;
using std::vector;

namespace chromeos_update_engine {

class ChromeBrowserProxyResolverTest : public ::testing::Test {
 protected:
  ChromeBrowserProxyResolverTest()
      : service_interface_mock_(new LibCrosServiceInterfaceProxyMock()),
        ue_proxy_resolved_interface_mock_(
            new UpdateEngineLibcrosProxyResolvedInterfaceProxyMock()),
        libcros_proxy_(
            brillo::make_unique_ptr(service_interface_mock_),
            brillo::make_unique_ptr(ue_proxy_resolved_interface_mock_)) {}

  void SetUp() override {
    loop_.SetAsCurrent();
    // The ProxyResolved signal should be subscribed to.
    MOCK_SIGNAL_HANDLER_EXPECT_SIGNAL_HANDLER(
        ue_proxy_resolved_signal_,
        *ue_proxy_resolved_interface_mock_,
        ProxyResolved);

    EXPECT_TRUE(resolver_.Init());
    // Run the loop once to dispatch the successfully registered signal handler.
    EXPECT_TRUE(loop_.RunOnce(false));
  }

  void TearDown() override {
    EXPECT_FALSE(loop_.PendingTasks());
  }

  // Send the signal to the callback passed during registration of the
  // ProxyResolved.
  void SendReplySignal(const string& source_url,
                       const string& proxy_info,
                       const string& error_message);

  void RunTest(bool chrome_replies, bool chrome_alive);

  brillo::FakeMessageLoop loop_{nullptr};

  // Local pointers to the mocks. The instances are owned by the
  // |libcros_proxy_|.
  LibCrosServiceInterfaceProxyMock* service_interface_mock_;
  UpdateEngineLibcrosProxyResolvedInterfaceProxyMock*
      ue_proxy_resolved_interface_mock_;

  // The registered signal handler for the signal
  // UpdateEngineLibcrosProxyResolvedInterface.ProxyResolved.
  chromeos_update_engine::dbus_test_utils::MockSignalHandler<
      void(const string&, const string&, const string&)>
      ue_proxy_resolved_signal_;

  LibCrosProxy libcros_proxy_;
  ChromeBrowserProxyResolver resolver_{&libcros_proxy_};
};


void ChromeBrowserProxyResolverTest::SendReplySignal(
    const string& source_url,
    const string& proxy_info,
    const string& error_message) {
  ASSERT_TRUE(ue_proxy_resolved_signal_.IsHandlerRegistered());
  ue_proxy_resolved_signal_.signal_callback().Run(
      source_url, proxy_info, error_message);
}

namespace {
void CheckResponseResolved(const deque<string>& proxies) {
  EXPECT_EQ(2U, proxies.size());
  EXPECT_EQ("socks5://192.168.52.83:5555", proxies[0]);
  EXPECT_EQ(kNoProxy, proxies[1]);
  MessageLoop::current()->BreakLoop();
}

void CheckResponseNoReply(const deque<string>& proxies) {
  EXPECT_EQ(1U, proxies.size());
  EXPECT_EQ(kNoProxy, proxies[0]);
  MessageLoop::current()->BreakLoop();
}
}  // namespace

// chrome_replies should be set to whether or not we fake a reply from
// chrome. If there's no reply, the resolver should time out.
// If chrome_alive is false, assume that sending to chrome fails.
void ChromeBrowserProxyResolverTest::RunTest(bool chrome_replies,
                                             bool chrome_alive) {
  char kUrl[] = "http://example.com/blah";
  char kProxyConfig[] = "SOCKS5 192.168.52.83:5555;DIRECT";

  EXPECT_CALL(*service_interface_mock_,
              ResolveNetworkProxy(StrEq(kUrl),
                                  StrEq(kLibCrosProxyResolveSignalInterface),
                                  StrEq(kLibCrosProxyResolveName),
                                  _,
                                  _))
      .WillOnce(Return(chrome_alive));

  ProxiesResolvedFn get_proxies_response = base::Bind(&CheckResponseNoReply);
  if (chrome_replies) {
    get_proxies_response = base::Bind(&CheckResponseResolved);
    MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&ChromeBrowserProxyResolverTest::SendReplySignal,
                   base::Unretained(this),
                   kUrl,
                   kProxyConfig,
                   ""),
        base::TimeDelta::FromSeconds(1));
  }

  EXPECT_NE(kProxyRequestIdNull,
            resolver_.GetProxiesForUrl(kUrl, get_proxies_response));
  MessageLoop::current()->Run();
}


TEST_F(ChromeBrowserProxyResolverTest, ParseTest) {
  // Test ideas from
  // http://src.chromium.org/svn/trunk/src/net/proxy/proxy_list_unittest.cc
  vector<string> inputs = {
      "PROXY foopy:10",
      " DIRECT",  // leading space.
      "PROXY foopy1 ; proxy foopy2;\t DIRECT",
      "proxy foopy1 ; SOCKS foopy2",
      "DIRECT ; proxy foopy1 ; DIRECT ; SOCKS5 foopy2;DIRECT ",
      "DIRECT ; proxy foopy1:80; DIRECT ; DIRECT",
      "PROXY-foopy:10",
      "PROXY",
      "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;",
      "HTTP foopy1; SOCKS5 foopy2"};
  vector<deque<string>> outputs = {
      {"http://foopy:10", kNoProxy},
      {kNoProxy},
      {"http://foopy1", "http://foopy2", kNoProxy},
      {"http://foopy1", "socks4://foopy2", kNoProxy},
      {kNoProxy, "http://foopy1", kNoProxy, "socks5://foopy2", kNoProxy},
      {kNoProxy, "http://foopy1:80", kNoProxy, kNoProxy},
      {kNoProxy},
      {kNoProxy},
      {"http://foopy1", "socks5://foopy2", kNoProxy},
      {"socks5://foopy2", kNoProxy}};
  ASSERT_EQ(inputs.size(), outputs.size());

  for (size_t i = 0; i < inputs.size(); i++) {
    deque<string> results =
        ChromeBrowserProxyResolver::ParseProxyString(inputs[i]);
    deque<string>& expected = outputs[i];
    EXPECT_EQ(results.size(), expected.size()) << "i = " << i;
    if (expected.size() != results.size())
      continue;
    for (size_t j = 0; j < expected.size(); j++) {
      EXPECT_EQ(expected[j], results[j]) << "i = " << i;
    }
  }
}

TEST_F(ChromeBrowserProxyResolverTest, SuccessTest) {
  RunTest(true, true);
}

TEST_F(ChromeBrowserProxyResolverTest, NoReplyTest) {
  RunTest(false, true);
}

TEST_F(ChromeBrowserProxyResolverTest, NoChromeTest) {
  RunTest(false, false);
}

TEST_F(ChromeBrowserProxyResolverTest, CancelCallbackTest) {
  int called = 0;
  auto callback = base::Bind(
      [](int* called, const deque<string>& proxies) { (*called)++; }, &called);

  EXPECT_CALL(*service_interface_mock_, ResolveNetworkProxy(_, _, _, _, _))
      .Times(4)
      .WillRepeatedly(Return(true));

  EXPECT_NE(kProxyRequestIdNull,
            resolver_.GetProxiesForUrl("http://urlA", callback));
  ProxyRequestId req_b = resolver_.GetProxiesForUrl("http://urlB", callback);
  // Note that we add twice the same url.
  ProxyRequestId req_c = resolver_.GetProxiesForUrl("http://urlC", callback);
  EXPECT_NE(kProxyRequestIdNull,
            resolver_.GetProxiesForUrl("http://urlC", callback));

  EXPECT_EQ(0, called);
  EXPECT_TRUE(resolver_.CancelProxyRequest(req_b));
  EXPECT_TRUE(resolver_.CancelProxyRequest(req_c));
  // Canceling the same request twice should fail even if there's another
  // request for the same URL.
  EXPECT_FALSE(resolver_.CancelProxyRequest(req_c));

  loop_.Run();
  EXPECT_EQ(2, called);
}

}  // namespace chromeos_update_engine
