// Copyright 2022 The Chromium OS 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 <string>
#include <utility>

#include <base/run_loop.h>
#include <base/test/bind.h>
#include <gtest/gtest.h>
#include <mojo/public/cpp/bindings/remote.h>

#include "mojo_service_manager/daemon/mojo_test_environment.h"
#include "mojo_service_manager/daemon/service_manager.h"
#include "mojo_service_manager/daemon/service_policy_test_util.h"
#include "mojo_service_manager/daemon/test.mojom.h"

namespace chromeos {
namespace mojo_service_manager {
namespace {

class ServiceManagerTestBase : public ::testing::Test {
 public:
  explicit ServiceManagerTestBase(Configuration config)
      : service_manager_(std::move(config),
                         CreateServicePolicyMapForTest({
                             {"FooService", {"owner", {"requester"}}},
                         })) {}

 protected:
  mojo::Remote<mojom::ServiceManager> ConnectServiceManagerAs(
      const std::string& security_context) {
    mojo::Remote<mojom::ServiceManager> remote;
    service_manager_.AddReceiver(
        mojom::ProcessIdentity::New(security_context, 0, 0, 0),
        remote.BindNewPipeAndPassReceiver());
    return remote;
  }

  MojoTaskEnvironment env_{base::test::TaskEnvironment::TimeSource::MOCK_TIME};

  ServiceManager service_manager_;
};

class ServiceManagerTest : public ServiceManagerTestBase {
 public:
  ServiceManagerTest() : ServiceManagerTestBase(Configuration{}) {}
};

class PermissiveServiceManagerTest : public ServiceManagerTestBase {
 public:
  PermissiveServiceManagerTest()
      : ServiceManagerTestBase(Configuration{.is_permissive = true}) {}
};

mojom::ErrorOrServiceStatePtr Query(
    const mojo::Remote<mojom::ServiceManager>& service_manager,
    const std::string& service_name) {
  mojom::ErrorOrServiceStatePtr result;
  base::RunLoop run_loop;
  service_manager->Query(service_name,
                         base::BindLambdaForTesting(
                             [&](mojom::ErrorOrServiceStatePtr result_inner) {
                               result = std::move(result_inner);
                               run_loop.Quit();
                             }));
  run_loop.Run();
  return result;
}

class FakeServcieProvider : public mojom::ServiceProvider, public mojom::Foo {
 public:
  // Overrides mojom::ServiceProvider.
  void Request(mojom::ProcessIdentityPtr client_identity,
               mojo::ScopedMessagePipeHandle receiver) override {
    CHECK(receiver.is_valid()) << "Receiver pipe is not valid.";
    last_client_identity_ = std::move(client_identity);
    foo_receiver_set_.Add(
        this, mojo::PendingReceiver<mojom::Foo>(std::move(receiver)));
  }

  // Overrides mojom::Foo.
  void Ping(PingCallback callback) override { std::move(callback).Run(); }

  mojo::Receiver<mojom::ServiceProvider> receiver_{this};

  mojo::ReceiverSet<mojom::Foo> foo_receiver_set_;

  mojom::ProcessIdentityPtr last_client_identity_;
};

void ExpectServiceProviderDisconnectWithError(FakeServcieProvider* provider,
                                              mojom::ErrorCode expected_error) {
  base::RunLoop run_loop;
  provider->receiver_.set_disconnect_with_reason_handler(
      base::BindLambdaForTesting(
          [&](uint32_t error, const std::string& message) {
            EXPECT_EQ(error, static_cast<uint32_t>(expected_error));
            run_loop.Quit();
          }));
  run_loop.Run();
}

class FakeServcieObserver : public mojom::ServiceObserver {
 public:
  // Overrides mojom::ServiceObserver.
  void OnServiceEvent(mojom::ServiceEventPtr event) override {
    last_event_ = std::move(event);
    if (callback_) {
      std::move(callback_).Run();
      callback_.Reset();
    }
  }

  mojo::Receiver<mojom::ServiceObserver> receiver_{this};

  base::OnceClosure callback_;

  mojom::ServiceEventPtr last_event_;
};

void ExpectServiceEvent(FakeServcieObserver* observer) {
  base::RunLoop run_loop;
  observer->callback_ = run_loop.QuitClosure();
  run_loop.Run();
}

void ExpectFooServiceConnected(mojo::Remote<mojom::Foo>* service) {
  service->set_disconnect_with_reason_handler(base::BindLambdaForTesting(
      [&](uint32_t error, const std::string& message) {
        CHECK(false) << "Reset with error: " << error
                     << ",message: " << message;
      }));
  service->FlushForTesting();
  CHECK(service->is_connected()) << "Foo service is disconnected.";
  service->set_disconnect_with_reason_handler(base::DoNothing());
  base::RunLoop run_loop;
  service->get()->Ping(run_loop.QuitClosure());
  run_loop.Run();
}

void ExpectFooServiceDisconnectWithError(mojo::Remote<mojom::Foo>* service,
                                         mojom::ErrorCode expected_error) {
  base::RunLoop run_loop;
  service->set_disconnect_with_reason_handler(base::BindLambdaForTesting(
      [&](uint32_t error, const std::string& message) {
        EXPECT_EQ(error, static_cast<uint32_t>(expected_error));
        run_loop.Quit();
      }));
  run_loop.Run();
}

TEST_F(ServiceManagerTest, RegisterAndUnregister) {
  FakeServcieProvider povider;
  ConnectServiceManagerAs("owner")->Register(
      "FooService", povider.receiver_.BindNewPipeAndPassRemote());

  EXPECT_EQ(Query(ConnectServiceManagerAs("requester"), "FooService"),
            mojom::ErrorOrServiceState::NewState(mojom::ServiceState::New(
                /*is_registered=*/true,
                /*owner=*/mojom::ProcessIdentity::New("owner", 0, 0, 0))));

  // Reset the receiver to unregister from service manager.
  povider.receiver_.reset();
  EXPECT_EQ(Query(ConnectServiceManagerAs("requester"), "FooService"),
            mojom::ErrorOrServiceState::NewState(mojom::ServiceState::New(
                /*is_registered=*/false, /*owner=*/nullptr)));
}

TEST_F(ServiceManagerTest, RegisterError) {
  {
    FakeServcieProvider povider;
    ConnectServiceManagerAs("owner")->Register(
        "NotFoundService", povider.receiver_.BindNewPipeAndPassRemote());
    ExpectServiceProviderDisconnectWithError(
        &povider, mojom::ErrorCode::kServiceNotFound);
  }
  {
    FakeServcieProvider povider;
    ConnectServiceManagerAs("not_owner")
        ->Register("FooService", povider.receiver_.BindNewPipeAndPassRemote());
    ExpectServiceProviderDisconnectWithError(
        &povider, mojom::ErrorCode::kPermissionDenied);
  }
  {
    auto remote = ConnectServiceManagerAs("owner");
    FakeServcieProvider povider1;
    FakeServcieProvider povider2;
    remote->Register("FooService",
                     povider1.receiver_.BindNewPipeAndPassRemote());
    remote->Register("FooService",
                     povider2.receiver_.BindNewPipeAndPassRemote());
    ExpectServiceProviderDisconnectWithError(
        &povider2, mojom::ErrorCode::kServiceHasBeenRegistered);
  }
}

TEST_F(ServiceManagerTest, Request) {
  FakeServcieProvider provider;
  ConnectServiceManagerAs("owner")->Register(
      "FooService", provider.receiver_.BindNewPipeAndPassRemote());

  mojo::Remote<mojom::Foo> foo;
  ConnectServiceManagerAs("requester")
      ->Request("FooService", std::nullopt,
                foo.BindNewPipeAndPassReceiver().PassPipe());
  ExpectFooServiceConnected(&foo);
  EXPECT_EQ(provider.last_client_identity_->security_context, "requester");
}

TEST_F(ServiceManagerTest, RequestBeforeRegister) {
  // Request without a timeout (set timeout to std::nullopt) so it will wait
  // until the service is registered.
  mojo::Remote<mojom::Foo> foo;
  ConnectServiceManagerAs("requester")
      ->Request("FooService", std::nullopt,
                foo.BindNewPipeAndPassReceiver().PassPipe());

  FakeServcieProvider provider;
  ConnectServiceManagerAs("owner")->Register(
      "FooService", provider.receiver_.BindNewPipeAndPassRemote());
  ExpectFooServiceConnected(&foo);
  EXPECT_EQ(provider.last_client_identity_->security_context, "requester");
}

TEST_F(ServiceManagerTest, RequestError) {
  {
    // Test service not found.
    mojo::Remote<mojom::Foo> foo;
    ConnectServiceManagerAs("requester")
        ->Request("NotFoundService", std::nullopt,
                  foo.BindNewPipeAndPassReceiver().PassPipe());
    ExpectFooServiceDisconnectWithError(&foo,
                                        mojom::ErrorCode::kServiceNotFound);
  }
  {
    // Test permission denied.
    mojo::Remote<mojom::Foo> foo;
    ConnectServiceManagerAs("not_a_requester")
        ->Request("FooService", std::nullopt,
                  foo.BindNewPipeAndPassReceiver().PassPipe());
    ExpectFooServiceDisconnectWithError(&foo,
                                        mojom::ErrorCode::kPermissionDenied);
  }
}

TEST_F(ServiceManagerTest, RequestTimeout) {
  auto remote = ConnectServiceManagerAs("requester");
  mojo::Remote<mojom::Foo> foo1;
  remote->Request("FooService", base::Seconds(0),
                  foo1.BindNewPipeAndPassReceiver().PassPipe());
  mojo::Remote<mojom::Foo> foo2;
  remote->Request("FooService", base::Seconds(5),
                  foo2.BindNewPipeAndPassReceiver().PassPipe());
  mojo::Remote<mojom::Foo> foo3;
  remote->Request("FooService", base::Seconds(10),
                  foo3.BindNewPipeAndPassReceiver().PassPipe());
  // No timeout.
  mojo::Remote<mojom::Foo> foo4;
  remote->Request("FooService", std::nullopt,
                  foo4.BindNewPipeAndPassReceiver().PassPipe());

  // Wait for the first two timeout.
  ExpectFooServiceDisconnectWithError(&foo1, mojom::ErrorCode::kTimeout);
  ExpectFooServiceDisconnectWithError(&foo2, mojom::ErrorCode::kTimeout);

  // Now it is at 5 seconds. Register the service so the rest of them can
  // connected successfully.
  FakeServcieProvider provider;
  ConnectServiceManagerAs("owner")->Register(
      "FooService", provider.receiver_.BindNewPipeAndPassRemote());
  ExpectFooServiceConnected(&foo3);
  ExpectFooServiceConnected(&foo4);
}

TEST_F(ServiceManagerTest, Query) {
  EXPECT_EQ(Query(ConnectServiceManagerAs("requester"), "FooService"),
            mojom::ErrorOrServiceState::NewState(mojom::ServiceState::New(
                /*is_registered=*/false, /*owner=*/nullptr)));
}

TEST_F(ServiceManagerTest, QueryError) {
  // Test service not found.
  EXPECT_EQ(Query(ConnectServiceManagerAs("requester"), "NotFoundService")
                ->get_error()
                ->code,
            mojom::ErrorCode::kServiceNotFound);

  // Test permission denied.
  EXPECT_EQ(Query(ConnectServiceManagerAs("not_requester"), "FooService")
                ->get_error()
                ->code,
            mojom::ErrorCode::kPermissionDenied);
}

TEST_F(ServiceManagerTest, ServiceObserverGetEvent) {
  FakeServcieObserver observer;
  ConnectServiceManagerAs("requester")
      ->AddServiceObserver(observer.receiver_.BindNewPipeAndPassRemote());

  FakeServcieProvider povider;
  ConnectServiceManagerAs("owner")->Register(
      "FooService", povider.receiver_.BindNewPipeAndPassRemote());
  ExpectServiceEvent(&observer);
  EXPECT_EQ(observer.last_event_,
            mojom::ServiceEvent::New(
                mojom::ServiceEvent::Type::kRegistered, "FooService",
                mojom::ProcessIdentity::New("owner", 0, 0, 0)));

  // Reset the receiver to unregister from service manager.
  povider.receiver_.reset();
  ExpectServiceEvent(&observer);
  EXPECT_EQ(observer.last_event_,
            mojom::ServiceEvent::New(
                mojom::ServiceEvent::Type::kUnRegistered, "FooService",
                mojom::ProcessIdentity::New("owner", 0, 0, 0)));
}

TEST_F(ServiceManagerTest, ServiceObserverNotRequester) {
  FakeServcieObserver observer_not_a_requester;
  ConnectServiceManagerAs("not_requester")
      ->AddServiceObserver(
          observer_not_a_requester.receiver_.BindNewPipeAndPassRemote());

  // Register a service and the observer should not receiver the event.
  FakeServcieProvider provider;
  ConnectServiceManagerAs("owner")->Register(
      "FooService", provider.receiver_.BindNewPipeAndPassRemote());

  // Run until all the async mojo operations are fulfilled.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(observer_not_a_requester.last_event_.is_null());
}

TEST_F(PermissiveServiceManagerTest, RegisterPermissive) {
  {
    // Test normal case.
    FakeServcieProvider povider;
    ConnectServiceManagerAs("owner")->Register(
        "FooService", povider.receiver_.BindNewPipeAndPassRemote());
    EXPECT_EQ(Query(ConnectServiceManagerAs("requester"), "FooService"),
              mojom::ErrorOrServiceState::NewState(mojom::ServiceState::New(
                  /*is_registered=*/true,
                  /*owner=*/mojom::ProcessIdentity::New("owner", 0, 0, 0))));
  }
  {
    // Test service can be owned by "not_owner".
    FakeServcieProvider povider;
    ConnectServiceManagerAs("not_owner")
        ->Register("FooService", povider.receiver_.BindNewPipeAndPassRemote());
    EXPECT_EQ(
        Query(ConnectServiceManagerAs("requester"), "FooService"),
        mojom::ErrorOrServiceState::NewState(mojom::ServiceState::New(
            /*is_registered=*/true,
            /*owner=*/mojom::ProcessIdentity::New("not_owner", 0, 0, 0))));
  }
  {
    // Test "NotInPolicyService" can be owned.
    FakeServcieProvider povider;
    ConnectServiceManagerAs("owner")->Register(
        "NotInPolicyService", povider.receiver_.BindNewPipeAndPassRemote());
    EXPECT_EQ(Query(ConnectServiceManagerAs("requester"), "NotInPolicyService"),
              mojom::ErrorOrServiceState::NewState(mojom::ServiceState::New(
                  /*is_registered=*/true,
                  /*owner=*/mojom::ProcessIdentity::New("owner", 0, 0, 0))));
  }
}

TEST_F(PermissiveServiceManagerTest, RequestPermissive) {
  {
    // Test normal case.
    FakeServcieProvider provider;
    ConnectServiceManagerAs("owner")->Register(
        "FooService", provider.receiver_.BindNewPipeAndPassRemote());

    mojo::Remote<mojom::Foo> foo;
    ConnectServiceManagerAs("requester")
        ->Request("FooService", std::nullopt,
                  foo.BindNewPipeAndPassReceiver().PassPipe());
    ExpectFooServiceConnected(&foo);
    EXPECT_EQ(provider.last_client_identity_->security_context, "requester");
  }
  {
    // Test request by not_requester.
    FakeServcieProvider provider;
    ConnectServiceManagerAs("owner")->Register(
        "FooService", provider.receiver_.BindNewPipeAndPassRemote());

    mojo::Remote<mojom::Foo> foo;
    ConnectServiceManagerAs("not_requester")
        ->Request("FooService", std::nullopt,
                  foo.BindNewPipeAndPassReceiver().PassPipe());
    ExpectFooServiceConnected(&foo);
    EXPECT_EQ(provider.last_client_identity_->security_context,
              "not_requester");
  }
  {
    // Test request NotInPolicyService.
    FakeServcieProvider provider;
    ConnectServiceManagerAs("owner")->Register(
        "NotInPolicyService", provider.receiver_.BindNewPipeAndPassRemote());

    mojo::Remote<mojom::Foo> foo;
    ConnectServiceManagerAs("requester")
        ->Request("NotInPolicyService", std::nullopt,
                  foo.BindNewPipeAndPassReceiver().PassPipe());
    ExpectFooServiceConnected(&foo);
    EXPECT_EQ(provider.last_client_identity_->security_context, "requester");
  }
}

TEST_F(PermissiveServiceManagerTest, RequestTimeoutPermissive) {
  {
    // Test normal case.
    mojo::Remote<mojom::Foo> foo;
    ConnectServiceManagerAs("requester")
        ->Request("FooService", base::Seconds(5),
                  foo.BindNewPipeAndPassReceiver().PassPipe());
    ExpectFooServiceDisconnectWithError(&foo, mojom::ErrorCode::kTimeout);
  }
  {
    // Test request by not_requester.
    mojo::Remote<mojom::Foo> foo;
    ConnectServiceManagerAs("not_requester")
        ->Request("FooService", base::Seconds(5),
                  foo.BindNewPipeAndPassReceiver().PassPipe());
    ExpectFooServiceDisconnectWithError(&foo, mojom::ErrorCode::kTimeout);
  }
  {
    // Test request NotInPolicyService.
    mojo::Remote<mojom::Foo> foo;
    ConnectServiceManagerAs("requester")
        ->Request("NotInPolicyService", base::Seconds(5),
                  foo.BindNewPipeAndPassReceiver().PassPipe());
    ExpectFooServiceDisconnectWithError(&foo, mojom::ErrorCode::kTimeout);
  }
}

TEST_F(PermissiveServiceManagerTest, QueryPermissive) {
  // Test service not found.
  EXPECT_EQ(Query(ConnectServiceManagerAs("requester"), "NotFoundService")
                ->get_error()
                ->code,
            mojom::ErrorCode::kServiceNotFound);

  // Test permission denied is not raised for not_requester.
  EXPECT_FALSE(Query(ConnectServiceManagerAs("not_requester"), "FooService")
                   ->is_error());

  // Test normal requester.
  EXPECT_FALSE(
      Query(ConnectServiceManagerAs("requester"), "FooService")->is_error());
}

TEST_F(PermissiveServiceManagerTest, ServiceObserverPermissive) {
  // Test if observer can receive events from services which it is not a
  // requester.
  FakeServcieObserver observer;
  ConnectServiceManagerAs("not_requester")
      ->AddServiceObserver(observer.receiver_.BindNewPipeAndPassRemote());

  FakeServcieProvider povider;
  ConnectServiceManagerAs("owner")->Register(
      "FooService", povider.receiver_.BindNewPipeAndPassRemote());
  ExpectServiceEvent(&observer);

  // Reset the receiver to unregister from service manager.
  povider.receiver_.reset();
  ExpectServiceEvent(&observer);
}

}  // namespace
}  // namespace mojo_service_manager
}  // namespace chromeos
