// Copyright 2016 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 "peridot/lib/firebase/event_stream.h"

#include <memory>
#include <string>
#include <utility>

#include <lib/async/cpp/task.h>

#include "gtest/gtest.h"
#include "lib/fsl/socket/strings.h"
#include "lib/fsl/tasks/message_loop.h"
#include "lib/fxl/macros.h"
#include "peridot/lib/socket/socket_pair.h"

namespace firebase {

class EventStreamTest : public ::testing::Test {
 public:
  EventStreamTest() {}
  ~EventStreamTest() override {}

 protected:
  // ApplicationTestBase:
  void SetUp() override {
    ::testing::Test::SetUp();
    socket::SocketPair socket;
    producer_socket_ = std::move(socket.socket1);
    event_stream_ = std::make_unique<EventStream>();
    event_stream_->Start(std::move(socket.socket2),
                         [this](Status status, const std::string& event,
                                const std::string& data) {
                           status_.push_back(status);
                           events_.push_back(event);
                           data_.push_back(data);
                           if (delete_on_event_) {
                             event_stream_.reset();
                           }
                         },
                         []() {});
  }

  void TearDown() override {
    producer_socket_.reset();
    ::testing::Test::TearDown();
  }

  void Feed(const std::string& data) {
    event_stream_->OnDataAvailable(data.data(), data.size());
  }

  void Done() { event_stream_->OnDataComplete(); }

  fsl::MessageLoop message_loop_;
  zx::socket producer_socket_;
  std::unique_ptr<EventStream> event_stream_;
  std::vector<Status> status_;
  std::vector<std::string> events_;
  std::vector<std::string> data_;
  bool delete_on_event_ = false;

 private:
  FXL_DISALLOW_COPY_AND_ASSIGN(EventStreamTest);
};

namespace {

TEST_F(EventStreamTest, OneEvent) {
  Feed("event: abc\ndata: bazinga\n\n");
  Done();

  EXPECT_EQ(1u, status_.size());
  EXPECT_EQ(Status::OK, status_[0]);
  EXPECT_EQ("abc", events_[0]);
  EXPECT_EQ("bazinga", data_[0]);
}

TEST_F(EventStreamTest, CutAtLineBreaks) {
  Feed("event: abc\n");
  Feed("data: bazinga\n");
  Feed("\n");
  Done();

  EXPECT_EQ(1u, status_.size());
  EXPECT_EQ(Status::OK, status_[0]);
  EXPECT_EQ("abc", events_[0]);
  EXPECT_EQ("bazinga", data_[0]);
}

TEST_F(EventStreamTest, CutInsideTag) {
  Feed("eve");
  Feed("nt: abc\n");
  Feed("da");
  Feed("ta: bazinga\n\n");
  Done();

  EXPECT_EQ(1u, status_.size());
  EXPECT_EQ(Status::OK, status_[0]);
  EXPECT_EQ("abc", events_[0]);
  EXPECT_EQ("bazinga", data_[0]);
}

TEST_F(EventStreamTest, CutInsideData) {
  Feed("event: abc\n");
  Feed("data: baz");
  Feed("inga\n\n");
  Done();

  EXPECT_EQ(1u, status_.size());
  EXPECT_EQ(Status::OK, status_[0]);
  EXPECT_EQ("abc", events_[0]);
  EXPECT_EQ("bazinga", data_[0]);
}

TEST_F(EventStreamTest, DataInMultipleLines) {
  Feed("event: abc\n");
  Feed("data: baz\n");
  Feed("data: in\ndata: ga\n");
  Feed("\n");
  Done();

  EXPECT_EQ(1u, status_.size());
  EXPECT_EQ(Status::OK, status_[0]);
  EXPECT_EQ("abc", events_[0]);
  EXPECT_EQ("baz\nin\nga", data_[0]);
}

TEST_F(EventStreamTest, IgnoreUnknownFieldNames) {
  Feed("event: abc\n");
  Feed("data: baz\n");
  Feed("trololo: trololo\n");  // Unknown field name.
  Feed("data: in\ndata: ga\n");
  Feed("\n");
  Done();

  EXPECT_EQ(1u, status_.size());
  EXPECT_EQ(Status::OK, status_[0]);
  EXPECT_EQ("abc", events_[0]);
  EXPECT_EQ("baz\nin\nga", data_[0]);
}

TEST_F(EventStreamTest, IgnoreLinesStartingWithColon) {
  Feed("event: abc\n");
  Feed(":ignore me, trololo\n");
  Feed("data: bazinga\n\n");
  Done();

  EXPECT_EQ(1u, status_.size());
  EXPECT_EQ(Status::OK, status_[0]);
  EXPECT_EQ("abc", events_[0]);
  EXPECT_EQ("bazinga", data_[0]);
}

TEST_F(EventStreamTest, MultipleEvents) {
  Feed("event: abc\n");
  Feed("data: bazinga\n\n");
  Feed("event: cde\n");
  Feed("data: 42\n\n");
  Feed("event: fgh\n");
  Feed("data: 50\n\n");
  Done();

  EXPECT_EQ(3u, status_.size());
  EXPECT_EQ(Status::OK, status_[0]);
  EXPECT_EQ("abc", events_[0]);
  EXPECT_EQ("bazinga", data_[0]);

  EXPECT_EQ(Status::OK, status_[1]);
  EXPECT_EQ("cde", events_[1]);
  EXPECT_EQ("42", data_[1]);

  EXPECT_EQ(Status::OK, status_[2]);
  EXPECT_EQ("fgh", events_[2]);
  EXPECT_EQ("50", data_[2]);
}

TEST_F(EventStreamTest, DeleteOnEvent) {
  delete_on_event_ = true;
  fsl::BlockingCopyFromString("event: abc\ndata: bazinga\n\n",
                              producer_socket_);
  async::PostTask(message_loop_.async(),
                  [this]() { message_loop_.PostQuitTask(); });
  message_loop_.Run();

  EXPECT_EQ(1u, status_.size());
  EXPECT_EQ(Status::OK, status_[0]);
  EXPECT_EQ("abc", events_[0]);
  EXPECT_EQ("bazinga", data_[0]);
}

}  // namespace
}  // namespace firebase
