// Copyright 2020 Google LLC
//
// 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 "connections/implementation/offline_service_controller.h"

#include <array>

#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "connections/implementation/offline_simulation_user.h"
#include "internal/platform/medium_environment.h"
#include "internal/platform/output_stream.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/logging.h"
#include "internal/platform/pipe.h"
#include "internal/platform/system_clock.h"

namespace location {
namespace nearby {
namespace connections {
namespace {

using ::testing::Eq;

constexpr std::array<char, 6> kFakeMacAddress = {'a', 'b', 'c', 'd', 'e', 'f'};
constexpr absl::string_view kServiceId = "service-id";
constexpr absl::string_view kDeviceA = "device-a";
constexpr absl::string_view kDeviceB = "device-b";
constexpr absl::string_view kMessage = "message";
constexpr absl::Duration kProgressTimeout = absl::Milliseconds(1500);
constexpr absl::Duration kDefaultTimeout = absl::Milliseconds(1500);
constexpr absl::Duration kDisconnectTimeout = absl::Milliseconds(15000);

constexpr BooleanMediumSelector kTestCases[] = {
    BooleanMediumSelector{
        .bluetooth = true,
    },
    BooleanMediumSelector{
        .wifi_lan = true,
    },
    BooleanMediumSelector{
        .bluetooth = true,
        .wifi_lan = true,
    },
};

class OfflineServiceControllerTest
    : public ::testing::TestWithParam<BooleanMediumSelector> {
 protected:
  OfflineServiceControllerTest() { env_.Stop(); }

  bool SetupConnection(OfflineSimulationUser& user_a,
                       OfflineSimulationUser& user_b) {
    user_a.StartAdvertising(std::string(kServiceId), &connect_latch_);
    user_b.StartDiscovery(std::string(kServiceId), &discover_latch_);
    EXPECT_TRUE(discover_latch_.Await(kDefaultTimeout).result());
    EXPECT_EQ(user_b.GetDiscovered().service_id, kServiceId);
    EXPECT_EQ(user_b.GetDiscovered().endpoint_info, user_a.GetInfo());
    EXPECT_FALSE(user_b.GetDiscovered().endpoint_id.empty());
    NEARBY_LOG(INFO, "EP-B: [discovered] %s",
               user_b.GetDiscovered().endpoint_id.c_str());
    user_b.RequestConnection(&connect_latch_);
    EXPECT_TRUE(connect_latch_.Await(kDefaultTimeout).result());
    EXPECT_FALSE(user_a.GetDiscovered().endpoint_id.empty());
    NEARBY_LOG(INFO, "EP-A: [discovered] %s",
               user_a.GetDiscovered().endpoint_id.c_str());
    NEARBY_LOG(INFO, "Both users discovered their peers.");
    user_a.AcceptConnection(&accept_latch_);
    user_b.AcceptConnection(&accept_latch_);
    EXPECT_TRUE(accept_latch_.Await(kDefaultTimeout).result());
    NEARBY_LOG(INFO, "Both users reached connected state.");
    return user_a.IsConnected() && user_b.IsConnected();
  }

  CountDownLatch discover_latch_{1};
  CountDownLatch lost_latch_{1};
  CountDownLatch connect_latch_{2};
  CountDownLatch accept_latch_{2};
  CountDownLatch payload_latch_{1};
  MediumEnvironment& env_ = MediumEnvironment::Instance();
};

TEST_P(OfflineServiceControllerTest, CanCreateOne) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanCreateMany) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanStartAdvertising) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  EXPECT_FALSE(user_a.IsAdvertising());
  EXPECT_THAT(user_a.StartAdvertising(std::string(kServiceId), nullptr),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(user_a.IsAdvertising());
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanStartDiscoveryBeforeAdvertising) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  EXPECT_FALSE(user_b.IsDiscovering());
  EXPECT_THAT(user_b.StartDiscovery(std::string(kServiceId), &discover_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(user_b.IsDiscovering());
  EXPECT_THAT(user_a.StartAdvertising(std::string(kServiceId), nullptr),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(discover_latch_.Await(kDefaultTimeout).result());
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanStartDiscoveryAfterAdvertising) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  EXPECT_FALSE(user_b.IsDiscovering());
  EXPECT_FALSE(user_b.IsAdvertising());
  EXPECT_THAT(user_a.StartAdvertising(std::string(kServiceId), nullptr),
              Eq(Status{Status::kSuccess}));
  EXPECT_THAT(user_b.StartDiscovery(std::string(kServiceId), &discover_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(user_a.IsAdvertising());
  EXPECT_TRUE(user_b.IsDiscovering());
  EXPECT_TRUE(discover_latch_.Await(kDefaultTimeout).result());
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanStopAdvertising) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  EXPECT_FALSE(user_a.IsAdvertising());
  EXPECT_THAT(user_a.StartAdvertising(std::string(kServiceId), nullptr),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(user_a.IsAdvertising());
  user_a.StopAdvertising();
  EXPECT_FALSE(user_a.IsAdvertising());
  EXPECT_THAT(user_b.StartDiscovery(std::string(kServiceId), &discover_latch_,
                                    &lost_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(user_b.IsDiscovering());
  auto discover_none = discover_latch_.Await(kDefaultTimeout).GetResult();
  if (!discover_none) {
    EXPECT_TRUE(true);
  } else {
    // There are rare cases (1/1000) that advertisment data has been captured by
    // discovery device before advertising is stopped. So we need to check if
    // lost_cb has grabbed the event in the end to prove the advertising service
    // is stopped.
    EXPECT_TRUE(lost_latch_.Await(kDefaultTimeout).result());
  }
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanStopDiscovery) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  EXPECT_FALSE(user_b.IsDiscovering());
  EXPECT_THAT(user_b.StartDiscovery(std::string(kServiceId), &discover_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(user_b.IsDiscovering());
  user_b.StopDiscovery();
  EXPECT_FALSE(user_b.IsDiscovering());
  EXPECT_THAT(user_a.StartAdvertising(std::string(kServiceId), nullptr),
              Eq(Status{Status::kSuccess}));
  EXPECT_FALSE(discover_latch_.Await(kDefaultTimeout).result());
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanConnect) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  EXPECT_THAT(user_a.StartAdvertising(std::string(kServiceId), &connect_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_THAT(user_b.StartDiscovery(std::string(kServiceId), &discover_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(discover_latch_.Await(kDefaultTimeout).result());
  EXPECT_THAT(user_b.RequestConnection(&connect_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(connect_latch_.Await(kDefaultTimeout).result());
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanAcceptConnection) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  EXPECT_THAT(user_a.StartAdvertising(std::string(kServiceId), &connect_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_THAT(user_b.StartDiscovery(std::string(kServiceId), &discover_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(discover_latch_.Await(kDefaultTimeout).result());
  EXPECT_THAT(user_b.RequestConnection(&connect_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(connect_latch_.Await(kDefaultTimeout).result());
  EXPECT_THAT(user_a.AcceptConnection(&accept_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_THAT(user_b.AcceptConnection(&accept_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(accept_latch_.Await(kDefaultTimeout).result());
  EXPECT_TRUE(user_a.IsConnected());
  EXPECT_TRUE(user_b.IsConnected());
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanRejectConnection) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  CountDownLatch reject_latch(1);
  EXPECT_THAT(user_a.StartAdvertising(std::string(kServiceId), &connect_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_THAT(user_b.StartDiscovery(std::string(kServiceId), &discover_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(discover_latch_.Await(kDefaultTimeout).result());
  EXPECT_THAT(user_b.RequestConnection(&connect_latch_),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(connect_latch_.Await(kDefaultTimeout).result());
  user_a.ExpectRejectedConnection(reject_latch);
  EXPECT_THAT(user_b.RejectConnection(nullptr), Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(reject_latch.Await(kDefaultTimeout).result());
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanSendBytePayload) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  ASSERT_TRUE(SetupConnection(user_a, user_b));
  ByteArray message(std::string{kMessage});
  user_a.SendPayload(Payload(message));
  user_b.ExpectPayload(payload_latch_);
  EXPECT_TRUE(payload_latch_.Await(kDefaultTimeout).result());
  EXPECT_EQ(user_b.GetPayload().AsBytes(), message);
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanSendStreamPayload) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  ASSERT_TRUE(SetupConnection(user_a, user_b));
  ByteArray message(std::string{kMessage});
  auto pipe = std::make_shared<Pipe>();
  OutputStream& tx = pipe->GetOutputStream();
  user_a.SendPayload(Payload([pipe]() -> InputStream& {
    return pipe->GetInputStream();  // NOLINT
  }));
  user_b.ExpectPayload(payload_latch_);
  tx.Write(message);
  EXPECT_TRUE(payload_latch_.Await(kDefaultTimeout).result());
  EXPECT_NE(user_b.GetPayload().AsStream(), nullptr);
  InputStream& rx = *user_b.GetPayload().AsStream();
  ASSERT_TRUE(user_b.WaitForProgress(
      [size = message.size()](const PayloadProgressInfo& info) -> bool {
        return info.bytes_transferred >= size;
      },
      kProgressTimeout));
  EXPECT_EQ(rx.Read(Pipe::kChunkSize).result(), message);
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanCancelStreamPayload) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  ASSERT_TRUE(SetupConnection(user_a, user_b));
  ByteArray message(std::string{kMessage});
  auto pipe = std::make_shared<Pipe>();
  OutputStream& tx = pipe->GetOutputStream();
  user_a.SendPayload(Payload([pipe]() -> InputStream& {
    return pipe->GetInputStream();  // NOLINT
  }));
  user_b.ExpectPayload(payload_latch_);
  tx.Write(message);
  EXPECT_TRUE(payload_latch_.Await(kDefaultTimeout).result());
  EXPECT_NE(user_b.GetPayload().AsStream(), nullptr);
  InputStream& rx = *user_b.GetPayload().AsStream();
  ASSERT_TRUE(user_b.WaitForProgress(
      [size = message.size()](const PayloadProgressInfo& info) -> bool {
        return info.bytes_transferred >= size;
      },
      kProgressTimeout));
  EXPECT_EQ(rx.Read(Pipe::kChunkSize).result(), message);
  user_b.CancelPayload();
  int count = 0;
  while (true) {
    count++;
    if (!tx.Write(message).Ok()) break;
    SystemClock::Sleep(kDefaultTimeout);
  }
  EXPECT_TRUE(user_a.WaitForProgress(
      [](const PayloadProgressInfo& info) -> bool {
        return info.status == PayloadProgressInfo::Status::kCanceled;
      },
      kProgressTimeout));
  EXPECT_LT(count, 10);
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

TEST_P(OfflineServiceControllerTest, CanDisconnect) {
  env_.Start();
  CountDownLatch disconnect_latch(1);
  OfflineSimulationUser user_a(kDeviceA, GetParam());
  OfflineSimulationUser user_b(kDeviceB, GetParam());
  ASSERT_TRUE(SetupConnection(user_a, user_b));
  NEARBY_LOGS(INFO) << "Disconnecting";
  user_b.ExpectDisconnect(disconnect_latch);
  user_b.Disconnect();
  EXPECT_TRUE(disconnect_latch.Await(kDisconnectTimeout).result());
  NEARBY_LOGS(INFO) << "Disconnected";
  EXPECT_FALSE(user_b.IsConnected());
  user_a.Stop();
  user_b.Stop();
  env_.Stop();
}

INSTANTIATE_TEST_SUITE_P(ParametrisedOfflineServiceControllerTest,
                         OfflineServiceControllerTest,
                         ::testing::ValuesIn(kTestCases));

// Verifies that InjectEndpoint() can be run successfully; does not test the
// full connection flow given that normal discovery/advertisement is skipped.
// Note: Not parameterized because InjectEndpoint only works over Bluetooth.
TEST_F(OfflineServiceControllerTest, InjectEndpoint) {
  env_.Start();
  OfflineSimulationUser user_a(kDeviceA,
                               BooleanMediumSelector{.bluetooth = true});
  EXPECT_THAT(user_a.StartDiscovery(std::string(kServiceId),
                                    /*found_latch=*/nullptr),
              Eq(Status{Status::kSuccess}));
  EXPECT_TRUE(user_a.IsDiscovering());
  user_a.InjectEndpoint(
      std::string(kServiceId),
      OutOfBandConnectionMetadata{
          .medium = Medium::BLUETOOTH,
          .remote_bluetooth_mac_address = ByteArray(kFakeMacAddress),
      });
  user_a.Stop();
  env_.Stop();
}

}  // namespace
}  // namespace connections
}  // namespace nearby
}  // namespace location
