// Copyright 2020 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 "gtest/gtest.h"
#include "pw_rpc/internal/hash.h"
#include "pw_rpc/nanopb_test_method_context.h"
#include "pw_rpc_test_protos/test.rpc.pb.h"

namespace pw::rpc {
namespace test {

class TestService final : public generated::TestService<TestService> {
 public:
  Status TestRpc(ServerContext&,
                 const pw_rpc_test_TestRequest& request,
                 pw_rpc_test_TestResponse& response) {
    response.value = request.integer + 1;
    return static_cast<Status::Code>(request.status_code);
  }

  void TestStreamRpc(ServerContext&,
                     const pw_rpc_test_TestRequest& request,
                     ServerWriter<pw_rpc_test_TestStreamResponse>& writer) {
    for (int i = 0; i < request.integer; ++i) {
      writer.Write({.chunk = {}, .number = static_cast<uint32_t>(i)});
    }

    writer.Finish(static_cast<Status::Code>(request.status_code));
  }
};

}  // namespace test

namespace {

TEST(NanopbCodegen, CompilesProperly) {
  test::TestService service;
  EXPECT_EQ(service.id(), internal::Hash("pw.rpc.test.TestService"));
  EXPECT_STREQ(service.name(), "TestService");
}

TEST(NanopbCodegen, InvokeUnaryRpc) {
  PW_NANOPB_TEST_METHOD_CONTEXT(test::TestService, TestRpc) context;

  EXPECT_EQ(Status::Ok(),
            context.call({.integer = 123, .status_code = Status::Ok()}));

  EXPECT_EQ(124, context.response().value);

  EXPECT_EQ(
      Status::InvalidArgument(),
      context.call({.integer = 999, .status_code = Status::InvalidArgument()}));
  EXPECT_EQ(1000, context.response().value);
}

TEST(NanopbCodegen, InvokeStreamingRpc) {
  PW_NANOPB_TEST_METHOD_CONTEXT(test::TestService, TestStreamRpc) context;

  context.call({.integer = 0, .status_code = Status::Aborted()});

  EXPECT_EQ(Status::Aborted(), context.status());
  EXPECT_TRUE(context.done());
  EXPECT_TRUE(context.responses().empty());
  EXPECT_EQ(0u, context.total_responses());

  context.call({.integer = 4, .status_code = Status::Ok()});

  ASSERT_EQ(4u, context.responses().size());
  ASSERT_EQ(4u, context.total_responses());

  for (size_t i = 0; i < context.responses().size(); ++i) {
    EXPECT_EQ(context.responses()[i].number, i);
  }

  EXPECT_EQ(Status::Ok(), context.status());
}

TEST(NanopbCodegen, InvokeStreamingRpc_ContextKeepsFixedNumberOfResponses) {
  PW_NANOPB_TEST_METHOD_CONTEXT(test::TestService, TestStreamRpc, 3) context;

  ASSERT_EQ(3u, context.responses().max_size());

  context.call({.integer = 5, .status_code = Status::NotFound()});

  ASSERT_EQ(3u, context.responses().size());
  ASSERT_EQ(5u, context.total_responses());

  EXPECT_EQ(context.responses()[0].number, 0u);
  EXPECT_EQ(context.responses()[1].number, 1u);
  EXPECT_EQ(context.responses()[2].number, 4u);
}

TEST(NanopbCodegen, InvokeStreamingRpc_ManualWriting) {
  PW_NANOPB_TEST_METHOD_CONTEXT(test::TestService, TestStreamRpc, 3) context;

  ASSERT_EQ(3u, context.responses().max_size());

  auto writer = context.writer();

  writer.Write({.chunk = {}, .number = 3});
  writer.Write({.chunk = {}, .number = 6});
  writer.Write({.chunk = {}, .number = 9});

  EXPECT_FALSE(context.done());

  writer.Finish(Status::Cancelled());
  ASSERT_TRUE(context.done());
  EXPECT_EQ(Status::Cancelled(), context.status());

  ASSERT_EQ(3u, context.responses().size());
  ASSERT_EQ(3u, context.total_responses());

  EXPECT_EQ(context.responses()[0].number, 3u);
  EXPECT_EQ(context.responses()[1].number, 6u);
  EXPECT_EQ(context.responses()[2].number, 9u);
}

}  // namespace
}  // namespace pw::rpc
