// 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 "peridot/lib/firebase_auth/testing/service_account_token_minter.h"

#include <lib/callback/capture.h>
#include <lib/callback/set_when_called.h>
#include <lib/fsl/vmo/strings.h>
#include <lib/fxl/files/file.h>
#include <lib/fxl/logging.h>
#include <lib/fxl/strings/string_number_conversions.h>
#include <lib/gtest/test_loop_fixture.h>
#include <lib/network_wrapper/fake_network_wrapper.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>

#include "peridot/lib/firebase_auth/testing/service_account_test_constants.h"
#include "peridot/lib/firebase_auth/testing/service_account_test_util.h"

namespace service_account {

namespace http = ::fuchsia::net::oldhttp;

namespace {

class ServiceAccountTokenMinterTest : public gtest::TestLoopFixture {
 public:
  ServiceAccountTokenMinterTest()
      : network_wrapper_(dispatcher()),
        token_minter_(&network_wrapper_,
                      Credentials::Parse(kTestServiceAccountConfig),
                      "user_id") {}

 protected:
  bool GetFirebaseToken(std::string api_key,
                        ServiceAccountTokenMinter::GetTokenResponse* response) {
    bool called;
    token_minter_.GetFirebaseToken(
        "api_key",
        callback::Capture(callback::SetWhenCalled(&called), response));
    RunLoopUntilIdle();
    return called;
  }

  std::string GetClientId() { return token_minter_.GetClientId(); }

  network_wrapper::FakeNetworkWrapper network_wrapper_;
  ServiceAccountTokenMinter token_minter_;
};

TEST_F(ServiceAccountTokenMinterTest, GetClientId) {
  EXPECT_FALSE(GetClientId().empty());
}

TEST_F(ServiceAccountTokenMinterTest, GetFirebaseToken) {
  network_wrapper_.SetResponse(GetResponseForTest(
      nullptr, 200, GetSuccessResponseBodyForTest("token", 3600)));

  ServiceAccountTokenMinter::GetTokenResponse resp;
  ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
  ASSERT_EQ(ServiceAccountTokenMinter::Status::OK, resp.status);
  ASSERT_EQ("token", resp.id_token);
}

TEST_F(ServiceAccountTokenMinterTest, GetFirebaseTokenFromCache) {
  network_wrapper_.SetResponse(GetResponseForTest(
      nullptr, 200, GetSuccessResponseBodyForTest("token", 3600)));

  ServiceAccountTokenMinter::GetTokenResponse resp;

  ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
  ASSERT_EQ(ServiceAccountTokenMinter::Status::OK, resp.status);
  ASSERT_EQ("token", resp.id_token);
  EXPECT_TRUE(network_wrapper_.GetRequest());

  network_wrapper_.ResetRequest();
  network_wrapper_.SetResponse(GetResponseForTest(
      nullptr, 200, GetSuccessResponseBodyForTest("token2", 3600)));

  ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
  ASSERT_EQ(ServiceAccountTokenMinter::Status::OK, resp.status);
  ASSERT_EQ("token", resp.id_token);
  EXPECT_FALSE(network_wrapper_.GetRequest());
}

TEST_F(ServiceAccountTokenMinterTest, GetFirebaseTokenNoCacheCache) {
  network_wrapper_.SetResponse(GetResponseForTest(
      nullptr, 200, GetSuccessResponseBodyForTest("token", 0)));

  ServiceAccountTokenMinter::GetTokenResponse resp;

  ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
  ASSERT_EQ(ServiceAccountTokenMinter::Status::OK, resp.status);
  ASSERT_EQ("token", resp.id_token);
  EXPECT_TRUE(network_wrapper_.GetRequest());

  network_wrapper_.ResetRequest();
  network_wrapper_.SetResponse(GetResponseForTest(
      nullptr, 200, GetSuccessResponseBodyForTest("token2", 3600)));

  ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
  ASSERT_EQ(ServiceAccountTokenMinter::Status::OK, resp.status);
  ASSERT_EQ("token2", resp.id_token);
  EXPECT_TRUE(network_wrapper_.GetRequest());
}

TEST_F(ServiceAccountTokenMinterTest, NetworkError) {
  auto network_status = http::HttpError::New();
  network_status->description = "Error";

  network_wrapper_.SetResponse(
      GetResponseForTest(std::move(network_status), 0, ""));

  ServiceAccountTokenMinter::GetTokenResponse resp;

  ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
  ASSERT_EQ(ServiceAccountTokenMinter::Status::NETWORK_ERROR, resp.status);
  EXPECT_TRUE(resp.id_token.empty());
  EXPECT_TRUE(network_wrapper_.GetRequest());
}

TEST_F(ServiceAccountTokenMinterTest, AuthenticationError) {
  network_wrapper_.SetResponse(
      GetResponseForTest(nullptr, 401, "Unauthorized"));

  ServiceAccountTokenMinter::GetTokenResponse resp;

  ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
  ASSERT_EQ(ServiceAccountTokenMinter::Status::AUTH_SERVER_ERROR, resp.status);
  EXPECT_TRUE(resp.id_token.empty());
  EXPECT_TRUE(network_wrapper_.GetRequest());
}

TEST_F(ServiceAccountTokenMinterTest, ResponseFormatError) {
  network_wrapper_.SetResponse(GetResponseForTest(nullptr, 200, ""));

  ServiceAccountTokenMinter::GetTokenResponse resp;

  ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
  ASSERT_EQ(ServiceAccountTokenMinter::Status::BAD_RESPONSE, resp.status);
  EXPECT_TRUE(resp.id_token.empty());
  EXPECT_TRUE(network_wrapper_.GetRequest());
}

}  // namespace
}  // namespace service_account
