// Copyright 2023 The Pigweed Authors
//
// 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
//
//     https://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 "pw_stream/socket_stream.h"

#include <thread>

#include "pw_result/result.h"
#include "pw_status/status.h"
#include "pw_unit_test/framework.h"

namespace pw::stream {
namespace {

// Helper function to create a ServerSocket and connect to it via loopback.
void RunConnectTest(const char* hostname) {
  ServerSocket server;
  EXPECT_EQ(server.Listen(), OkStatus());

  Result<SocketStream> server_stream = Status::Unavailable();
  auto accept_thread = std::thread{[&]() { server_stream = server.Accept(); }};

  SocketStream client;
  EXPECT_EQ(client.Connect(hostname, server.port()), OkStatus());

  accept_thread.join();
  EXPECT_EQ(server_stream.status(), OkStatus());

  server_stream.value().Close();
  server.Close();
  client.Close();
}

TEST(SocketStreamTest, ConnectLocalhost) { RunConnectTest("localhost"); }

TEST(SocketStreamTest, ConnectIpv4) { RunConnectTest("127.0.0.1"); }

TEST(SocketStreamTest, ConnectIpv6) { RunConnectTest("::1"); }

TEST(SocketStreamTest, ConnectDefault) { RunConnectTest(nullptr); }

TEST(SocketStreamTest, ConnectSpecificPort) {
  // We want to test the "listen on a specific port" functionality,
  // but hard-coding a port number in a test is inherently problematic, as
  // port numbers are a global resource.
  //
  // We use the automatic port assignment initially to get a port assignment,
  // close that server, and then use that port explicitly in a new server.
  //
  // There's still the possibility that the port will get swiped, but it
  // shouldn't happen by chance.
  ServerSocket initial_server;
  EXPECT_EQ(initial_server.Listen(), OkStatus());
  uint16_t port = initial_server.port();
  initial_server.Close();

  ServerSocket server;
  EXPECT_EQ(server.Listen(port), OkStatus());
  EXPECT_EQ(server.port(), port);

  Result<SocketStream> server_stream = Status::Unavailable();
  auto accept_thread = std::thread{[&]() { server_stream = server.Accept(); }};

  SocketStream client;
  EXPECT_EQ(client.Connect("localhost", server.port()), OkStatus());
  EXPECT_TRUE(client.IsReady());

  accept_thread.join();
  EXPECT_EQ(server_stream.status(), OkStatus());

  server_stream.value().Close();
  server.Close();
  client.Close();
  EXPECT_FALSE(client.IsReady());
}

// Helper function to test exchanging data on a pair of sockets.
void ExchangeData(SocketStream& stream1, SocketStream& stream2) {
  auto kPayload1 = as_bytes(span("some data"));
  auto kPayload2 = as_bytes(span("other bytes"));
  std::array<char, 100> read_buffer{};

  // Write data from stream1 and read it from stream2.
  auto write_status = Status::Unavailable();
  auto write_thread =
      std::thread{[&]() { write_status = stream1.Write(kPayload1); }};
  Result<ByteSpan> read_result =
      stream2.Read(as_writable_bytes(span(read_buffer)));
  EXPECT_EQ(read_result.status(), OkStatus());
  EXPECT_EQ(read_result.value().size(), kPayload1.size());
  EXPECT_TRUE(
      std::equal(kPayload1.begin(), kPayload1.end(), read_result->begin()));

  write_thread.join();
  EXPECT_EQ(write_status, OkStatus());

  // Read data in the client and write it from the server.
  auto read_thread = std::thread{[&]() {
    read_result = stream1.Read(as_writable_bytes(span(read_buffer)));
  }};
  EXPECT_EQ(stream2.Write(kPayload2), OkStatus());

  read_thread.join();
  EXPECT_EQ(read_result.status(), OkStatus());
  EXPECT_EQ(read_result.value().size(), kPayload2.size());
  EXPECT_TRUE(
      std::equal(kPayload2.begin(), kPayload2.end(), read_result->begin()));

  // Close stream1 and attempt to read from stream2.
  stream1.Close();
  read_result = stream2.Read(as_writable_bytes(span(read_buffer)));
  EXPECT_EQ(read_result.status(), Status::OutOfRange());

  stream2.Close();
}

TEST(SocketStreamTest, ReadWrite) {
  ServerSocket server;
  EXPECT_EQ(server.Listen(), OkStatus());

  Result<SocketStream> server_stream = Status::Unavailable();
  auto accept_thread = std::thread{[&]() { server_stream = server.Accept(); }};

  SocketStream client;
  EXPECT_EQ(client.Connect("localhost", server.port()), OkStatus());

  accept_thread.join();
  EXPECT_EQ(server_stream.status(), OkStatus());

  ExchangeData(client, server_stream.value());
  server.Close();
}

TEST(SocketStreamTest, MultipleClients) {
  ServerSocket server;
  EXPECT_EQ(server.Listen(), OkStatus());

  Result<SocketStream> server_stream1 = Status::Unavailable();
  Result<SocketStream> server_stream2 = Status::Unavailable();
  Result<SocketStream> server_stream3 = Status::Unavailable();
  auto accept_thread = std::thread{[&]() {
    server_stream1 = server.Accept();
    server_stream2 = server.Accept();
    server_stream3 = server.Accept();
  }};

  SocketStream client1;
  SocketStream client2;
  SocketStream client3;
  EXPECT_EQ(client1.Connect("localhost", server.port()), OkStatus());
  EXPECT_EQ(client2.Connect("localhost", server.port()), OkStatus());
  EXPECT_EQ(client3.Connect("localhost", server.port()), OkStatus());

  accept_thread.join();
  EXPECT_EQ(server_stream1.status(), OkStatus());
  EXPECT_EQ(server_stream2.status(), OkStatus());
  EXPECT_EQ(server_stream3.status(), OkStatus());

  ExchangeData(client1, server_stream1.value());
  ExchangeData(client2, server_stream2.value());
  ExchangeData(client3, server_stream3.value());
  server.Close();
}

TEST(SocketStreamTest, ReuseAutomaticServerPort) {
  uint16_t server_port = 0;
  SocketStream client_stream;
  ServerSocket server;

  EXPECT_EQ(server.Listen(0), OkStatus());
  server_port = server.port();
  EXPECT_NE(server_port, 0);

  Result<SocketStream> server_stream = Status::Unavailable();
  auto accept_thread = std::thread{[&]() { server_stream = server.Accept(); }};

  EXPECT_EQ(client_stream.Connect(nullptr, server_port), OkStatus());
  accept_thread.join();
  ASSERT_EQ(server_stream.status(), OkStatus());

  server_stream->Close();
  server.Close();

  ServerSocket server2;
  EXPECT_EQ(server2.Listen(server_port), OkStatus());
}

}  // namespace
}  // namespace pw::stream
