// Copyright 2020 The Chromium 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 "media/capture/video/chromeos/token_manager.h"

#include <grp.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "chromeos/components/sensors/ash/sensor_hal_dispatcher.h"

namespace {

gid_t GetArcCameraGid() {
  auto* group = getgrnam("arc-camera");
  return group != nullptr ? group->gr_gid : 0;
}

bool EnsureTokenDirectoryExists(const base::FilePath& token_path) {
  static const gid_t gid = GetArcCameraGid();
  if (gid == 0) {
    LOG(ERROR) << "Failed to query the GID of arc-camera";
    return false;
  }

  base::FilePath dir_name = token_path.DirName();
  if (!base::CreateDirectory(dir_name) ||
      !base::SetPosixFilePermissions(dir_name, 0770)) {
    LOG(ERROR) << "Failed to create token directory at "
               << token_path.AsUTF8Unsafe();
    return false;
  }

  if (chown(dir_name.AsUTF8Unsafe().c_str(), -1, gid) != 0) {
    LOG(ERROR) << "Failed to chown token directory to arc-camera";
    return false;
  }
  return true;
}

bool WriteTokenToFile(const base::FilePath& token_path,
                      const base::UnguessableToken& token) {
  if (!EnsureTokenDirectoryExists(token_path)) {
    LOG(ERROR) << "Failed to ensure token directory exists";
    return false;
  }
  base::File token_file(
      token_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
  if (!token_file.IsValid()) {
    LOG(ERROR) << "Failed to create token file at "
               << token_path.AsUTF8Unsafe();
    return false;
  }
  std::string token_string = token.ToString();
  token_file.WriteAtCurrentPos(token_string.c_str(), token_string.length());
  return true;
}

}  // namespace

namespace media {

constexpr char TokenManager::kServerTokenPath[];
constexpr char TokenManager::kServerSensorClientTokenPath[];
constexpr char TokenManager::kTestClientTokenPath[];
constexpr std::array<cros::mojom::CameraClientType, 3>
    TokenManager::kTrustedClientTypes;

TokenManager::TokenManager() = default;
TokenManager::~TokenManager() = default;

bool TokenManager::GenerateServerToken() {
  server_token_ = base::UnguessableToken::Create();
  return WriteTokenToFile(base::FilePath(kServerTokenPath), server_token_);
}

bool TokenManager::GenerateServerSensorClientToken() {
  auto* sensor_hal_dispatcher =
      chromeos::sensors::SensorHalDispatcher::GetInstance();
  if (!sensor_hal_dispatcher)
    return false;

  return WriteTokenToFile(base::FilePath(kServerSensorClientTokenPath),
                          sensor_hal_dispatcher->GetTokenForTrustedClient());
}

bool TokenManager::GenerateTestClientToken() {
  return WriteTokenToFile(
      base::FilePath(kTestClientTokenPath),
      GetTokenForTrustedClient(cros::mojom::CameraClientType::TESTING));
}

base::UnguessableToken TokenManager::GetTokenForTrustedClient(
    cros::mojom::CameraClientType type) {
  base::AutoLock l(client_token_map_lock_);
  if (std::find(kTrustedClientTypes.begin(), kTrustedClientTypes.end(), type) ==
      kTrustedClientTypes.end()) {
    return base::UnguessableToken();
  }
  auto& token_set = client_token_map_[type];
  if (token_set.empty()) {
    token_set.insert(base::UnguessableToken::Create());
  }
  return *token_set.begin();
}

void TokenManager::RegisterPluginVmToken(const base::UnguessableToken& token) {
  base::AutoLock l(client_token_map_lock_);
  auto result =
      client_token_map_[cros::mojom::CameraClientType::PLUGINVM].insert(token);
  if (!result.second) {
    LOG(WARNING) << "The same token is already registered";
  }
}

void TokenManager::UnregisterPluginVmToken(
    const base::UnguessableToken& token) {
  base::AutoLock l(client_token_map_lock_);
  auto num_removed =
      client_token_map_[cros::mojom::CameraClientType::PLUGINVM].erase(token);
  if (num_removed != 1) {
    LOG(WARNING) << "The token wasn't registered previously";
  }
}

bool TokenManager::AuthenticateServer(const base::UnguessableToken& token) {
  DCHECK(!server_token_.is_empty());
  return server_token_ == token;
}

bool TokenManager::AuthenticateServerSensorClient(
    const base::UnguessableToken& token) {
  auto* sensor_hal_dispatcher =
      chromeos::sensors::SensorHalDispatcher::GetInstance();
  if (!sensor_hal_dispatcher)
    return false;

  return sensor_hal_dispatcher->AuthenticateClient(token);
}

absl::optional<cros::mojom::CameraClientType> TokenManager::AuthenticateClient(
    cros::mojom::CameraClientType type,
    const base::UnguessableToken& token) {
  base::AutoLock l(client_token_map_lock_);
  if (type == cros::mojom::CameraClientType::UNKNOWN) {
    for (const auto& client_token_map_pair : client_token_map_) {
      const auto& token_set = client_token_map_pair.second;
      if (token_set.find(token) != token_set.end()) {
        return client_token_map_pair.first;
      }
    }
    return absl::nullopt;
  }
  auto& token_set = client_token_map_[type];
  if (token_set.find(token) == token_set.end()) {
    return absl::nullopt;
  }
  return type;
}

void TokenManager::AssignServerTokenForTesting(
    const base::UnguessableToken& token) {
  server_token_ = token;
}

void TokenManager::AssignClientTokenForTesting(
    cros::mojom::CameraClientType type,
    const base::UnguessableToken& token) {
  base::AutoLock l(client_token_map_lock_);
  client_token_map_[type].insert(token);
}

}  // namespace media
