/*
 *  Copyright 2009 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <memory>
#include <string>
#include "rtc_base/gunit.h"
#include "rtc_base/proxyserver.h"
#include "rtc_base/socketadapters.h"
#include "rtc_base/testclient.h"
#include "rtc_base/testechoserver.h"
#include "rtc_base/virtualsocketserver.h"

using rtc::Socket;
using rtc::SocketAddress;

static const SocketAddress kSocksProxyIntAddr("1.2.3.4", 1080);
static const SocketAddress kSocksProxyExtAddr("1.2.3.5", 0);
static const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999);

// Sets up a virtual socket server and a SOCKS5 proxy server.
class ProxyTest : public testing::Test {
 public:
  ProxyTest() : ss_(new rtc::VirtualSocketServer()), thread_(ss_.get()) {
    socks_.reset(new rtc::SocksProxyServer(ss_.get(), kSocksProxyIntAddr,
                                           ss_.get(), kSocksProxyExtAddr));
  }

  rtc::SocketServer* ss() { return ss_.get(); }

 private:
  std::unique_ptr<rtc::SocketServer> ss_;
  rtc::AutoSocketServerThread thread_;
  std::unique_ptr<rtc::SocksProxyServer> socks_;
};

// Tests whether we can use a SOCKS5 proxy to connect to a server.
TEST_F(ProxyTest, TestSocks5Connect) {
  rtc::AsyncSocket* socket =
      ss()->CreateAsyncSocket(kSocksProxyIntAddr.family(), SOCK_STREAM);
  rtc::AsyncSocksProxySocket* proxy_socket = new rtc::AsyncSocksProxySocket(
      socket, kSocksProxyIntAddr, "", rtc::CryptString());
  // TODO: IPv6-ize these tests when proxy supports IPv6.

  rtc::TestEchoServer server(rtc::Thread::Current(),
                             SocketAddress(INADDR_ANY, 0));

  std::unique_ptr<rtc::AsyncTCPSocket> packet_socket(
      rtc::AsyncTCPSocket::Create(proxy_socket, SocketAddress(INADDR_ANY, 0),
                                  server.address()));
  EXPECT_TRUE(packet_socket != nullptr);
  rtc::TestClient client(std::move(packet_socket));

  EXPECT_EQ(Socket::CS_CONNECTING, proxy_socket->GetState());
  EXPECT_TRUE(client.CheckConnected());
  EXPECT_EQ(Socket::CS_CONNECTED, proxy_socket->GetState());
  EXPECT_EQ(server.address(), client.remote_address());
  client.Send("foo", 3);
  EXPECT_TRUE(client.CheckNextPacket("foo", 3, nullptr));
  EXPECT_TRUE(client.CheckNoPacket());
}
