/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 <boost/test/unit_test.hpp>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TServerSocket.h>
#include <memory>
#include "TTransportCheckThrow.h"
#include <iostream>

using apache::thrift::transport::TServerSocket;
using apache::thrift::transport::TSocket;
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
using std::shared_ptr;

BOOST_AUTO_TEST_SUITE(TServerSocketTest)

BOOST_AUTO_TEST_CASE(test_bind_to_address) {
  TServerSocket sock1("localhost", 0);
  sock1.listen();
  BOOST_CHECK(sock1.isOpen());
  int port = sock1.getPort();
  TSocket clientSock("localhost", port);
  clientSock.open();
  shared_ptr<TTransport> accepted = sock1.accept();
  accepted->close();
  sock1.close();

  std::cout << "An error message from getaddrinfo on the console is expected:" << '\n';
  TServerSocket sock2("257.258.259.260", 0);
  BOOST_CHECK_THROW(sock2.listen(), TTransportException);
  sock2.close();
}

BOOST_AUTO_TEST_CASE(test_listen_invalid_port) {
  TServerSocket sock1(-1);
  TTRANSPORT_CHECK_THROW(sock1.listen(), TTransportException::BAD_ARGS);
  BOOST_CHECK(!sock1.isOpen());

  TServerSocket sock2(65536);
  TTRANSPORT_CHECK_THROW(sock2.listen(), TTransportException::BAD_ARGS);
  BOOST_CHECK(!sock1.isOpen());
}

BOOST_AUTO_TEST_CASE(test_close_before_listen) {
  TServerSocket sock1("localhost", 0);
  sock1.close();
  BOOST_CHECK(!sock1.isOpen());
}

BOOST_AUTO_TEST_CASE(test_get_port) {
  TServerSocket sock1("localHost", 888);
  BOOST_CHECK_EQUAL(888, sock1.getPort());
}

BOOST_AUTO_TEST_SUITE_END()
