// Copyright 2018 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 "garnet/lib/overnet/protocol/routable_message.h"
#include "gtest/gtest.h"

namespace overnet {
namespace routing_header_test {

typedef std::vector<uint8_t> BinVec;

template <class T>
BinVec Encode(const T& x) {
  auto sz = x.wire_length();
  BinVec out;
  out.resize(sz);
  x.Write(out.data());
  return out;
}

template <class T>
BinVec EncodeVarint(const T& x) {
  auto sz = x.wire_length();
  BinVec out;
  out.resize(sz);
  x.Write(sz, out.data());
  return out;
}

TEST(BaseTypes, NodeId) {
  NodeId one(1);
  NodeId two(2);
  NodeId also_one(1);

  EXPECT_EQ(one, also_one);
  EXPECT_NE(one, two);
  EXPECT_EQ((BinVec{1, 0, 0, 0, 0, 0, 0, 0}), Encode(one));
  EXPECT_EQ((BinVec{2, 0, 0, 0, 0, 0, 0, 0}), Encode(two));
}

TEST(BaseTypes, StreamId) {
  StreamId one(1);
  StreamId two(2);
  StreamId also_one(1);

  EXPECT_EQ(one, also_one);
  EXPECT_NE(one, two);
  EXPECT_EQ((BinVec{1}), EncodeVarint(one));
  EXPECT_EQ((BinVec{2}), EncodeVarint(two));
}

static void RoundTrip(const RoutableMessage& rh, NodeId sender, NodeId receiver,
                      Slice payload) {
  auto enc = rh.Write(sender, receiver, payload);
  auto prs_status = RoutableMessage::Parse(enc, receiver, sender);
  EXPECT_TRUE(prs_status.is_ok()) << prs_status.AsStatus();
  EXPECT_EQ(rh, prs_status->message);
  EXPECT_EQ(payload, prs_status->payload);
}

TEST(RoutableMessage, PayloadWrite1) {
  auto rh = std::move(RoutableMessage(NodeId(1)).AddDestination(
      NodeId(2), StreamId(1), SeqNum(1, 10)));
  auto body = Slice::FromContainer({1, 2, 3});
  // encode locally
  EXPECT_EQ(Slice::FromContainer({// flags
                                  0,
                                  // dests {
                                  // [0] =
                                  //   stream_id
                                  1,
                                  //   seqnum
                                  1,
                                  // }
                                  // payload
                                  1, 2, 3}),
            rh.Write(NodeId(1), NodeId(2), body));
  RoundTrip(rh, NodeId(1), NodeId(2), body);
}

TEST(RoutableMessage, PayloadWrite2) {
  auto rh = std::move(RoutableMessage(NodeId(1)).AddDestination(
      NodeId(2), StreamId(1), SeqNum(1, 10)));
  auto body = Slice::FromContainer({1, 2, 3});
  // encode along a different route
  EXPECT_EQ(Slice::FromContainer({// flags
                                  (1 << 4),
                                  // src
                                  1, 0, 0, 0, 0, 0, 0, 0,
                                  // dests {
                                  // [0] =
                                  //   node
                                  2, 0, 0, 0, 0, 0, 0, 0,
                                  //   stream_id
                                  1,
                                  //   seqnum
                                  1,
                                  // }
                                  // payload
                                  1, 2, 3}),
            rh.Write(NodeId(4), NodeId(2), body));
  RoundTrip(rh, NodeId(4), NodeId(2), body);
}

TEST(RoutableMessage, PayloadWrite3) {
  auto rh =
      std::move(RoutableMessage(NodeId(1))
                    .AddDestination(NodeId(2), StreamId(1), SeqNum(1, 10))
                    .AddDestination(NodeId(3), StreamId(42), SeqNum(7, 10)));
  auto body = Slice::FromContainer({7, 8, 9});
  EXPECT_EQ(Slice::FromContainer({// flags
                                  (2 << 4),
                                  // src
                                  1, 0, 0, 0, 0, 0, 0, 0,
                                  // dests {
                                  // [0] =
                                  //   node
                                  2, 0, 0, 0, 0, 0, 0, 0,
                                  //   stream_id
                                  1,
                                  //   seqnum
                                  1,
                                  // [1] =
                                  //   node
                                  3, 0, 0, 0, 0, 0, 0, 0,
                                  //   stream_id
                                  42,
                                  //   seqnum
                                  7,
                                  // }
                                  // payload
                                  7, 8, 9}),
            rh.Write(NodeId(1), NodeId(2), body));
  RoundTrip(rh, NodeId(1), NodeId(2), body);
}

}  // namespace routing_header_test
}  // namespace overnet
