// 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 "src/virtualization/tests/lib/guest_console.h"

#include <memory>
#include <string>
#include <vector>

#include <gtest/gtest.h>

#include "src/virtualization/tests/lib/socket.h"

namespace {

class FakeSocket : public SocketInterface {
 public:
  explicit FakeSocket(std::vector<std::string> responses) : responses_(std::move(responses)) {}

  zx_status_t Send(zx::time deadline, const std::string& message) override { return ZX_OK; }

  zx_status_t Receive(zx::time deadline, std::string* result) override {
    if (reads_performed_ >= responses_.size()) {
      return ZX_ERR_PEER_CLOSED;
    }
    *result = responses_.at(reads_performed_);
    reads_performed_++;
    return ZX_OK;
  }

  zx_status_t WaitForClosed(zx::time deadline) override { return ZX_OK; }

 private:
  size_t reads_performed_ = 0;
  std::vector<std::string> responses_;
};

TEST(GuestConsole, WaitForMarkerEmpty) {
  auto socket = std::make_unique<FakeSocket>(std::vector<std::string>{});
  GuestConsole console(std::move(socket));

  // Ensure an empty read returns success, and clears out result.
  std::string result = "non-empty";
  EXPECT_EQ(console.WaitForMarker("", zx::time::infinite(), &result), ZX_OK);
  EXPECT_EQ(result, "");

  // A non-empty marker read should return an error.
  EXPECT_EQ(console.WaitForMarker("x", zx::time::infinite(), &result), ZX_ERR_PEER_CLOSED);
}

TEST(GuestConsole, WaitForMarkerSimple) {
  auto socket = std::make_unique<FakeSocket>(std::vector<std::string>{"marker"});
  GuestConsole console(std::move(socket));

  std::string result;
  EXPECT_EQ(console.WaitForMarker("marker", zx::time::infinite(), &result), ZX_OK);
  EXPECT_EQ(result, "");
}

TEST(GuestConsole, WaitForMarkerContentBefore) {
  auto socket = std::make_unique<FakeSocket>(std::vector<std::string>{"xxxmarker"});
  GuestConsole console(std::move(socket));

  std::string result;
  EXPECT_EQ(console.WaitForMarker("marker", zx::time::infinite(), &result), ZX_OK);
  EXPECT_EQ(result, "xxx");
}

TEST(GuestConsole, WaitForMarkerContentAfterPreserved) {
  auto socket = std::make_unique<FakeSocket>(std::vector<std::string>{"xxxmarkeryyy", "second"});
  GuestConsole console(std::move(socket));

  std::string result;
  EXPECT_EQ(console.WaitForMarker("marker", zx::time::infinite(), &result), ZX_OK);
  EXPECT_EQ(result, "xxx");

  EXPECT_EQ(console.WaitForMarker("second", zx::time::infinite(), &result), ZX_OK);
  EXPECT_EQ(result, "yyy");
}

TEST(GuestConsole, WaitForMarkerSplitMarker) {
  // "xxx" + "marker" + "yyy" + "second"
  auto socket = std::make_unique<FakeSocket>(
      std::vector<std::string>{"xx", "xm", "ar", "keryyys", "econ", "d"});
  GuestConsole console(std::move(socket));

  std::string result;
  EXPECT_EQ(console.WaitForMarker("marker", zx::time::infinite(), &result), ZX_OK);
  EXPECT_EQ(result, "xxx");

  EXPECT_EQ(console.WaitForMarker("second", zx::time::infinite(), &result), ZX_OK);
  EXPECT_EQ(result, "yyy");
}

}  // namespace
