// Copyright 2020 The Fuchsia 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 <sys/time.h>

#include <condition_variable>
#include <memory>
#include <mutex>
#include <thread>

#include <gtest/gtest.h>

#include "src/developer/shell/mirror/client.h"
#include "src/developer/shell/mirror/command_line_options.h"
#include "src/developer/shell/mirror/server.h"
#include "src/developer/shell/mirror/test_shared.h"

namespace shell::mirror {

class ClientServerTest : public ::testing::Test {
 public:
  ClientServerTest() {}
};

class MessageLoopHolder {
 public:
  explicit MessageLoopHolder(std::unique_ptr<debug::PlatformMessageLoop> ptr)
      : ptr_(std::move(ptr)) {}
  ~MessageLoopHolder() { ptr_->Cleanup(); }
  debug::PlatformMessageLoop* operator->() { return ptr_.get(); }
  debug::PlatformMessageLoop* get() { return ptr_.get(); }

 private:
  std::unique_ptr<debug::PlatformMessageLoop> ptr_;
};

TEST_F(ClientServerTest, RoundTrip) {
  const std::string kDataDir = "/client_server_test_tmp";
  FileRepo repo(&kAsyncLoopConfigNoAttachToCurrentThread);
  repo.InitMemRepo(kDataDir);

  // Generate some fake files.
  std::vector<std::pair<std::string, std::string>> golden = {
      {kDataDir + "/z.txt", ""},
      {kDataDir + "/a.txt", "Once upon a midnight dreary, while I pondered, weak and weary,"},
      {kDataDir + "/b.txt", "Over many a quaint and curious volume of forgotten lore"},
      {kDataDir + "/c.txt", "While I nodded, nearly napping, suddenly there came a tapping,"},
      {kDataDir + "/d.txt", "As of some one gently rapping, rapping at my chamber door."}};

  repo.WriteFiles(golden);

  CommandLineOptions options;
  options.port = 0;
  options.path = kDataDir;

  std::condition_variable cond_var;
  std::mutex mutex;
  uint16_t port;

  std::thread server_thread([&options, &cond_var, &port]() {
    SocketServer server;
    SocketServer::ConnectionConfig config;
    config.port = options.port;
    config.path = options.path;
    Err err = server.RunInLoop(config, FROM_HERE, [&cond_var, &server, &port]() {
      port = server.GetPort();
      cond_var.notify_all();
    });
    ASSERT_TRUE(err.ok()) << err.msg;
  });

  // Wait until the server has started.
  {
    std::unique_lock<std::mutex> l(mutex);
    cond_var.wait(l);
  }

  std::string host_and_port = "[::1]:" + std::to_string(port);

  // Initialize connection and load results.
  client::ClientConnection load_connection;
  Err err = load_connection.Init(host_and_port);
  ASSERT_TRUE(err.ok()) << err.msg;
  // Impossibly high timeout, because we're a test.
  struct timeval tv;
  tv.tv_sec = 10000;
  tv.tv_usec = 0;
  Files files;
  err = load_connection.Load(&files, &tv);
  ASSERT_TRUE(err.ok()) << err.msg;

  // Initialize connection and kill server.
  client::ClientConnection kill_connection;
  err = kill_connection.Init(host_and_port);
  ASSERT_TRUE(err.ok()) << err.msg;
  err = kill_connection.KillServer();
  ASSERT_TRUE(err.ok()) << err.msg;
  server_thread.join();

  // Make sure results are as expected.
  ASSERT_EQ(files.size(), golden.size());
  for (const auto& file : files) {
    const auto& data = file.View();
    const auto& name = file.Name();
    bool found = false;
    for (size_t i = 0; i < golden.size(); i++) {
      if ((golden[i].first.substr(kDataDir.length() + 1) == name) && (golden[i].second == data)) {
        found = true;
        break;
      }
    }
    ASSERT_TRUE(found) << "Not found in expected: " << name << " with data \"" << data << "\"";
  }
}

}  // namespace shell::mirror
